Arrange one or more text labels to fit inside a polygon.
Usage
label_fill_JamPolygon(
jp,
labels,
buffer = -0.15,
width_buffer = 0.1,
relative = TRUE,
color = "black",
border = NA,
ref_jp = NULL,
xyratio = 1.1,
fontsize = 10,
cex = 1,
degrees = 0,
jitter_cex = 0.04,
jitter_color = 0.07,
jitter_degrees = 0,
apply_n_scale = TRUE,
label_method = c("hexagonal"),
draw_labels = TRUE,
seed = 1,
plot_style = c("none", "JamPolygon"),
verbose = FALSE,
...
)
Arguments
- jp
JamPolygon
where only the first row is processed.- labels
character
vector of labels- buffer
numeric
value (default-0.15
) buffer to resize the polygon, where negative values shrink the polygon size relative to the size of the polygon. For example-0.9
will reduce the polygon 90% of the way toward a completely empty polygon, where that range is defined by the width inside the polygon border.- width_buffer
numeric
passed tosample_JamPolygon()
to apply a "width buffer", using values relative to the maximumbuffer
size. This mechanism is experimental, to try to improve label placement in unusually-shaped polygons.width_buffer=0
will add no additional bufferwidth_buffer=0.5
will apply width buffer equal to half the buffer size required to create an empty polygon. The polygon is shifted left and right by half this amount each direction, then the intersection is used. This method has the intention of requiring a certain available width, for example for wide text labels.
- relative
logical
passed tobuffer_JamPolygon()
(defaultTRUE
) to definebuffer
with relative coordinates.- color
character
string to define the color of resulting labels.- border
character
string used to define an optional item border, which is only useful whengridtext
is used to visualize labels.- ref_jp
JamPolygon
(optional) used only whenapply_n_scale=TRUE
, used to define the overall plot range before determining whether the internal area ofjp
should be reduced before arraying item label coordinates. The general idea is that polygons which are a smaller percentage of the total area should not be reduced as much byapply_n_scale
because they have limited area, but larger polygons should receive closer to the fullapply_n_scale
adjustment.- xyratio
numeric
value indicating the relative ratio of x (width) to y (height) when arraying coordinates inside the polygons. Values larger than1
will place points wider from each other than they are tall, which can help with longer text labels.- fontsize
numeric
font size in points, default10
.- cex
numeric
multiplied byfontsize
as an alternative convenient way to adjust text label sizes.- degrees
numeric
value used to rotate labels, default0
, in degrees between 0 and 359.- apply_n_scale
logical
indicating whether to adjust the buffer based upon the number of items, where more items uses less buffer, and fewer items imposes a larger buffer. The intent is for a single label or small number of labels to appear near the center.- label_method
character
string (default "hexagonal") to define the label layout. Currently only"hexagonal"
is implemented. After testing some approaches insf::st_sample()
andspatstat.random::rThomas()
, the other options were interesting but ultimately not more effective specifically for character labels. Both packages have heavy R dependencies and were avoided.- draw_labels
logical
(defaultTRUE
) indicating whether to draw labels, however it is only used whenplot_style="JamPolygon"
. Note also, when drawing labels, it assumes the plot is already created usingref_jp
, and it determines the coordinate adjustments relative toref_jp
.- seed
numeric
value (default1
) used to define the random seed withset.seed(seed)
for reproducible output. Whenseed
isNULL
there is no call toset.seed()
.- plot_style
character
string, default "none"."none"
: No plot output."JamPolygon"
: assumeref_jp
has already been plotted, and labels should be drawn in that coordinate context. For example callplot(ref_jp)
thenlabel_fill_JamPolygon(jp, ref_jp, plot_output="JamPolygon")
. See examples.
- verbose
logical
indicating whether to print verbose output.- ...
additional arguments are passed to internal functions:
buffer_JamPolygon()
, andsample_JamPolygon()
.- `jitter_cex, jitter_color, jitter_degrees`
values used to provide some variability to the repeated pattern of text labels.
jitter_cex
provides a range to adjustcex
andfontsize
slightly for each label, making some slightly larger or smaller to help distinguish adjacent labels from one another.jitter_color
provides a range for adjusting the font color, which is applied withdarkFactor
injamba::makeColorDarker()
.jitter_degrees
provides a range for adjusting fontdegrees
, the default0
means the values are not adjusted. Thetext()
function does not permit multiple vectorized rotations, howevergridtext
does permit multiple angles. Best to usejitter_degrees
only when displaying labels withgridtext
.
Value
list
when there are valid coordinates, NULL
otherwise.
The list
contains these elements:
"items_df"
: adata.frame
with columnsx,y,text,rot,color,fontsize,border
"g_labels"
: a gridgrob
graphical object only whenplot_style="base"
, otherwiseNULL
"scale_width"
: anumeric
value indicating thebuffer
used"jp_buffer"
: aJamPolygon
object after adjusting withbuffer
Details
This function is intended to define points inside a polygon area so that text labels can be roughly evenly spaced, with relatively good default positioning to minimize overlapping labels. This function does not prevent overlapping labels, nor does it fully prevent labels overlapping the polygon border.
There are options to help minimize overlapping labels, such as xyratio
which defines the default width-to-height ratio of resulting points.
For wider text labels, a higher value for xyratio
may be helpful.
To minimize adjacent (side-by-side) label overlaps, it can be helpful
to use degrees
to rotate labels slightly, for example degrees=5
may be enough to prevent wide labels from overlapping the next label
beside it.
Strategy
Determine bounding box with rectangular area that encompases the polygon.
Define evenly spaced points across the rectangular area sufficient to produce at least
n
total points.Retain only the subset of points which are inside the polygon.
If there are fewer than
n
remaining points, repeat the process using a higher target value forn
.
Todo
Modify options that plot the result so they work together with
plot.JamPolygon()
.
See also
Other JamPolygon:
JamPolygon-class
,
Venndir-class
,
[,JamPolygon,ANY,ANY,ANY-method
,
add_orientation_JamPolygon()
,
area_JamPolygon()
,
bbox_JamPolygon()
,
buffer_JamPolygon()
,
check_JamPolygon()
,
check_Venndir()
,
eulerr_to_JamPolygon()
,
farthest_point_JamPolygon()
,
find_venn_overlaps_JamPolygon()
,
has_point_in_JamPolygon()
,
intersect_JamPolygon()
,
label_outside_JamPolygon()
,
label_segment_JamPolygon()
,
labelr_JamPolygon()
,
minus_JamPolygon()
,
nearest_point_JamPolygon()
,
nudge_JamPolygon()
,
plot.JamPolygon()
,
point_in_JamPolygon()
,
polyclip_to_JamPolygon()
,
polygon_circles()
,
polygon_ellipses()
,
sample_JamPolygon()
,
split_JamPolygon()
,
union_JamPolygon()
,
update_JamPolygon()
Examples
df3 <- data.frame(name=c("polygon1", "polygon2"),
label=c("polygon1", "polygon2"),
x=I(list(
list(c(1, 6, 6, 1),
c(2, 5, 5, 2),
c(3, 4, 4, 3)),
list(#c(11, 16, 16, 11),
c(12, 15, 15, 12),
c(13, 14, 14, 13))
)),
y=I(list(
list(c(1, 1, 6, 6),
c(2, 2, 5, 5),
c(3, 3, 4, 4)),
list(#c(1, 1, 6, 6),
c(2, 2, 5, 5),
c(3, 3, 4, 4))
)),
fill=c("gold", "firebrick"))
jp3 <- new("JamPolygon", polygons=df3);
jp3p <- plot(jp3);
lfj1 <- label_fill_JamPolygon(jp3[1,], labels=rep("O", 100),
ref_jp=jp3, plot_style="JamPolygon")
lfj2 <- label_fill_JamPolygon(jp3[2,], labels=rep("X", 40),
buffer=-0.5,
ref_jp=jp3, plot_style="JamPolygon")
jp3p <- plot(jp3);
lfj1 <- label_fill_JamPolygon(jp3[1,], labels=rep("O", 1), apply_n_scale=FALSE,
ref_jp=jp3, plot_style="JamPolygon")