An add-on to Luxor.jl, this aids with placing labels automatically for readability. Selective labels display is useful for geographical maps and other diagrams.
The image shows labels pointing at random points on a circle, and with random priority. Some labels are hidden, because of priority and overlapping other labels' text or their anchor point. The default label plotting function was used.
begin
Drawing(300, 150, "firsttry.svg")
background("gold")
label_all_at_given_offset(txt = ["A", "B"],
x = [100, 200], y = 50, # Both labels get y = 50
shadowcolor = Luxor.parse(Colorant, "Gold4"), # Too fancy?
textcolor = Luxor.parse.(Colorant, ["red", "blue"]))
finish()
end
The user interface functions all take the same list of keyword arguments. They convey 'what to do' in the function names, and use keywords to define the label content.
These terms are used as part of function names.
prioritized
means: Drop labels that can't be plotted without overlapping other labels. The function returns information about which (if any) were dropped.all
means: Plot all labelsat given offset
: Don't try to find the best offset direction.optimize diagonal offset
: If labels overlap, flip offset diagonally (a 2-satisfiability problem). Often the best choice since leader lines remain parallel (looking good).optimize vertical offset
: If labels overlap, flip vertically.optimize horizontal offset
: Good for placing labels around a vertical line.optimize offset
: Text offset to any quadrant. A 4-satisfiability problem, slow, and often produces less readable output since leader lines (if enabled) are not parallel.bounding boxes
: Don't actually plot, just return the boxes where text would go.
The terms above are combined into function names. We thought this might be easier to remember than a whole lot of new keyword combinations. It works for us.
label_prioritized_at_given_offset
label_prioritized_optimize_vertical_offset
label_prioritized_optimize_horizontal_offset
label_prioritized_optimize_diagonal_offset
indexes_and_bbs_prioritized_at_given_offset
label_prioritized_optimize_offset
label_all_at_given_offset
label_all_optimize_vertical_offset
label_all_optimize_horizontal_offset
label_all_optimize_diagonal_offset
label_all_optimize_offset
indexes_and_bbs_all_at_given_offset
Keywords are used to generate labels data. See inline docs for LabelPaperSpace
and the default
plotting function, plot_label_return_bb
.
Most keywords are similar to Luxor / Cairo's text
functionality.
The prominence
property affects how labels are prioritized, and their font size.
prominence = 1.0
is used for the most important labels. When labels are dropped
because of overlap, these are the last to be dropped.
You can also specify your own label plotting function, for example by copying and tweaking the default plot_label_return_bb
. To be useful with label optimization, it should output a bounding box as well as graphics. Your function needs to accept the keyword 'suppress', but does not need to use it.
Restrain a label from flipping by setting fixpos
. See PosEnum
.
Prevent a label from interaction with others by setting collision_free
.
Identiy problematic label interactions by setting ENV["JULIA_DEBUG"] = "LuxorLabels"
See the test folder for examples.
Example of a ruler. We should perhaps have given prominence 1 to 0, 10, 20, 30?
Example of a box, where prominence is given to 0, 10, 20, 30. 2nd priority is given to 5, 15 etc.:
Example of a default label in all four (default) offset positions. Keyword plot_guides
is set to true
.
The label placement optimization uses JuMP.jl with a solver from GNU project GLPK.jl.
You also need to use Luxor.jl, of course.