The current plot I have looks as follows.
The code for it is this:
ggplot(data, aes(x = factor(Class), y = dry_r45, group = 1)) +
stat_slabinterval(aes(y = dry_r45), interval_color = NA, fill = NA, slab_linewidth = 0.7, slab_color = "#DDCC77", point_color = "#DDCC77") +
stat_slabinterval(aes(y = mddl_45), interval_color = NA, fill = NA, slab_linewidth = 0.7, slab_color = "#44AA99", point_color = "#44AA99") +
stat_slabinterval(aes(y = wt_rc45), interval_color = NA, fill = NA, slab_linewidth = 0.7, slab_color = "#CC6677", point_color = "#CC6677") +
labs(title = "Density plot for drought exposure, mddl, and wt by Class") +
theme_minimal() +
facet_wrap(~ Class, nrow = 2,scales="free") +coord_flip() +ylim(0,1000)
This is all great, but I I'd like to get rid of all the empty space below each subplot, (negative Y-space), and make sure the lines don't collide with the dots (so move up the lines a bit). I can't figure out how to make it so the 'negative space' in the y-axis gets removed, and I also can't seem to move the dots or lines separately because I think they are called from within the same stat_slabinterval argument.
Some sample data:
structure(list(Class = structure(c(1L, 1L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 1L, 1L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 4L, 3L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 4L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 4L, 3L), levels = c("AMPHIBIA", "AVES", "MAMMALIA", "REPTILIA"
), class = "factor"), dry_r45 = c(363.388145949796, 131.155995859126,
392.051280340233, 582.12436836741, 633.665139548256, 183.849416151781,
122.220776927914, 123.221302688033, 664.803469572132, 282.41950446681,
428.865496826172, 638.74445964881, 573.595947613427, 736.178894042969,
631.199749226331, 865.028329673332, 184.875174569854, 592.06201171875,
424.021702785801, 406.961345310191, 957.064789292682, 288.912997795784,
334.388577027565, 624.237691191004, 566.094641214125, 965.949048973318,
1086.51134631976, 818.705607823815, 812.030196080853, 418.2314861611,
930.134145798456, 355.866535987484, 684.294302829476, 556.960110937029,
398.931482238751, 752.938455770096, 462.381468014355, 398.031650214026,
298.475676238082, 404.424822059044, 256.658201651774, 596.230151226608,
729.547485581456, 625.906604886473, 1013.6908622825, 276.346704896106,
410.053284821958, 541.667721972739, 681.618416008016, 795.054924532415,
846.914624371795, 1015.57506061187, 611.549468843312, 607.54233085132,
214.093516755057, 387.734687936783, 847.17546192728, 331.378194899786,
73.4170806285058, 951.697522815941, 408.532844147008, 412.570369907525,
281.967407737638, 657.175493623395, 279.812453602327, 244.635951289973,
872.925850282055, 1261.37923860897, 1235.22716577741, 697.819079558861,
410.057326599648, 418.804483814327, 837.981430449478, 149.541834271081,
264.866667957967), mddl_45 = c(230.500439431837, 163.710847456737,
299.96951929863, 423.873927877018, 440.698367818376, 136.399273290044,
152.50591804705, 214.297180644848, 722.051286387759, 274.571592029772,
262.856053161621, 357.064670976097, 295.897055939346, 351.93798828125,
708.99732498796, 667.473720823298, 117.744196577975, 496.816101074219,
373.646014965177, 419.876292813853, 747.141463729431, 249.665116104439,
364.860711117477, 444.033146888809, 535.850235853449, 710.513437306163,
827.295865526503, 653.396152980815, 757.848262892133, 507.858365499264,
743.698141956148, 370.792797109154, 288.362213316226, 479.384836448459,
446.564511233827, 772.255513162575, 517.041371310898, 308.440145695875,
374.333019052753, 322.049826190655, 304.716008620463, 710.442666526399,
592.912785708139, 428.822896338398, 710.029178335925, 619.404727700808,
415.426429585988, 408.516053370282, 413.470117480482, 637.426605185107,
576.462000244721, 815.561222733534, 716.702217131378, 778.149816356721,
398.577447637592, 324.873910004304, 628.970334656669, 106.597244141594,
208.704991215036, 643.954423847175, 417.634095213485, 416.941213162062,
443.085707354952, 727.496359936908, 344.487907053418, 329.172377352853,
621.26261704873, 789.666201080418, 824.791253843076, 736.890392529379,
415.414993990779, 411.323582996079, 639.800383809321, 222.484497747311,
242.336969253859), wt_rc45 = c(76.3325505422698, 26.0749306037862,
213.660518472799, 223.602243746736, 260.973150763789, 99.5864348594492,
69.4877840233901, -0.007544409787213, 165.824787692528, 201.850371611746,
268.678361129761, 179.384988762923, 300.252028279575, 643.518493652344,
70.0349630538731, 313.892097528487, 62.9863443202421, 551.368432617188,
138.110343445225, 127.724954321858, 309.662423873126, 73.4286095145551,
89.386721275755, 402.7680647483, 178.621465983978, 292.085215506391,
317.640496352263, 345.16239351255, 495.180555146173, 272.436864661596,
319.123857185159, 90.7415581058763, 246.418129166891, 201.391396672138,
113.457046621468, 227.448114313626, 198.105969728023, 220.517736183205,
99.8547521656706, 235.885256335919, 138.281499654164, 194.346132279175,
461.937739263605, 244.087637602723, 272.772766122321, -17.0701460841088,
136.625117421999, 213.479783690862, 265.529688418323, 284.292623990206,
236.246770851961, 352.069942762743, 186.821549232814, 113.429620774066,
19.0431269788363, 235.247781032165, 297.818652483379, 67.7614093356662,
28.8775403752636, 205.488691354048, 134.06130174424, 137.646887953974,
66.2057470847847, 176.012013026833, 56.2544402972126, 37.3199555074739,
146.257366275971, 245.445828631319, 239.06573905842, 150.303573937585,
136.63193962908, 142.41180761378, 331.730189780207, 70.0905639991735,
93.7739139260316)), row.names = c(NA, 75L), class = "data.frame")
First, I'll note that I've swapped your x
and y
aesthetic mappings and removed coord_flip()
, since this is equivalent but (in my opinion) easier to reason about.
I've also replaced (what would have been) + xlim(0, 1000)
with + coord_cartesian(xlim = c(0, 1000))
, as the former is generally not recommended. xlim()
and ylim()
remove data rather than simply changing the visible limits, which will change the results of summary statistics (indeed, I got warnings about missing data on your example dataset).
On to your specific questions...
The axis space is created by the fact that you have mapped a factor onto the y
axis. By default, ggplot2 places pretty generous spacing at the edges of x
/y
axes with factors mapped onto them, which works well when you have factors with more than a few levels but can be too much with just a level or two. You can control this by passing an expansion()
value to the expand
argument of corresponding scale_...
function.
For example:
ggplot(data, aes(y = factor(Class), x = dry_r45, group = 1)) +
stat_slabinterval(aes(x = dry_r45), interval_color = NA, fill = NA, slab_linewidth = 0.7, slab_color = "#DDCC77", point_color = "#DDCC77") +
stat_slabinterval(aes(x = mddl_45), interval_color = NA, fill = NA, slab_linewidth = 0.7, slab_color = "#44AA99", point_color = "#44AA99") +
stat_slabinterval(aes(x = wt_rc45), interval_color = NA, fill = NA, slab_linewidth = 0.7, slab_color = "#CC6677", point_color = "#CC6677") +
labs(title = "Density plot for drought exposure, mddl, and wt by Class") +
theme_minimal() +
facet_wrap(~ Class, nrow = 2,scales="free") +
coord_cartesian(xlim = c(0,1000)) +
# add a smaller-than-default expansion amount at the scale edge
scale_y_discrete(expand = expansion(add = 0.1))
To separate the point from the slabs, you can always use stat_slab() + stat_pointinterval()
as an alternative to stat_slabinterval()
.
However, doing that with your current code would then lead to adding six layers to the plot, each with very similar settings. I'd prefer to avoid the code duplication, so I'll first transform the data into long format so we can map the different variables onto the color
aesthetic. Besides saving code duplication, this will allow us to add a legend.
I'll also set the y
variable to a blank value since it is redundant to the facet titles:
data |>
# this will give a `name` column with "dry_r45", "mddl_45",
# and "wt_rc45" and a corresponding `value` column
tidyr::pivot_longer(c(dry_r45, mddl_45, wt_rc45)) |>
ggplot(aes(y = "", x = value)) +
stat_slab(aes(color = name), fill = NA, linewidth = 0.7) +
# .width = 0 suppresses the interval and height = 0 ensures
# extra blank space above/below the pointinterval is not added
stat_pointinterval(aes(color = name), .width = 0, height = 0) +
labs(title = "Density plot for drought exposure, mddl, and wt by Class") +
theme_minimal() +
facet_wrap(~ Class, nrow = 2,scales="free") +
coord_cartesian(xlim = c(0,1000)) +
scale_y_discrete(expand = expansion(add = 0.1)) +
# instead of repeatedly specifying colors in separate layers
# we used aes(color = name) above and specify the colors here
scale_color_manual(values = c(dry_r45 = "#DDCC77", mddl_45 = "#44AA99", wt_rc45 = "#CC6677"))
From here, you should be able to (for example) add something like position = position_nudge(y = -0.1)
to the stat_pointinterval()
or stat_slab()
layer to move it up or down separately from the other layer.