Using ggplot2's guide-axis n.dodge = 2, I get the following:
Is there a (hopefully simple) way to extend the tick marks for the three labels on the right, so that they become some sort of leader lines?
Using ggplot2's guide-axis n.dodge = 2, I get the following:
Is there a (hopefully simple) way to extend the tick marks for the three labels on the right, so that they become some sort of leader lines?
The code in this answer was made by Shawn Taylor and accessed at the following link: https://gist.github.com/sdtaylor/4f92f0e620aada78ae4c07472d20d973. I simply copy the code and the output here in case the link no longer works in the future.
library(tibble)
library(ggplot2)
library(forcats)
#------------------------------------
# Have x-axis labels offset slightly for clarity using guide_axis(n.dodge = 2),
# but also have different length tickmarks to make it look nicer.
# See https://twitter.com/ecologyofgavin/status/1344102509585997824
# Derived from https://stackoverflow.com/a/51312611/6615512
# Requires ggplot 3.0.0 or greater
#------------------------------------
# Some data to plot
lizards = tribble(
~group, ~n,
'Ag', 5,
'0-3', 8,
'8-10', 7.5,
'12-15',8,
'20-32',7.8,
'Natural',8.1
)
# put groups in order defined above
lizards$group = fct_inorder(lizards$group)
# Tick mark lengths adjusted here
top_y_pos = 2
bot_y_pos = 0.8
custom_ticks = tribble(
~group, ~y_end,
'Ag', top_y_pos,
'0-3', bot_y_pos,
'8-10', top_y_pos,
'12-15', bot_y_pos,
'20-32', top_y_pos,
'Natural',bot_y_pos
)
ggplot(lizards, aes(x=group,y=n)) +
geom_point(aes(color=group),size=8) +
scale_color_viridis_d() +
scale_x_discrete(guide = guide_axis(n.dodge = 2)) +
geom_linerange(data = custom_ticks, aes(x=group, ymax=2.7, ymin=y_end), # The custom tickmarks
size=2,
inherit.aes = F) +
theme_bw(50) +
coord_cartesian(clip='off', ylim=c(3,10)) + # clip off allow geoms, here the tickmarks, to be drawn outside the plots
theme(legend.position = 'none',
axis.title = element_blank(),
panel.border = element_rect(color='black'), # make the border and y ticks match the custom ticks
axis.ticks.y = element_line(color='black'),
axis.ticks.x = element_blank()) # turn offf the regular tickmarks
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
Created on 2023-01-03 with reprex v2.0.2
I recently spent quite a bit of time banging my head on this for a more general solution: Here's one I came up with based largely on this other StackOverflow solution.
This function elongates every other tick along a certain axis (and thus generalizes across facets:
library(tidyverse)
library(grid)
library(gridExtra)
add_dodged_ticks <- function(plot, axis = 'bottom') {
plot_grob <- ggplotGrob(plot)
plot_grob$layout %>% as.tibble() %>%
rownames_to_column('index') %>%
filter(str_detect(name, paste0('axis-',axis[0]))) %>%
pull(index) %>% as.numeric() %>%
map(function(x) {
ticks <- plot_grob$grobs[[x]]$children[[2]]$grobs[[1]]$y
fourseq <- ifelse(length(ticks) < 3, 3, length(ticks))
for (i in 1:length(ticks)) {
if (i %in% seq(3, fourseq, 4)) {
plot_grob$grobs[[x]]$children[[2]]$grobs[[1]]$y[[i]] <<- unit(1,'npc') - unit(12,'pt')
}
}
})
return(plot_grob)
}
I was successfully able to convert the output of this function (a ggplotGrob) to a regular ggplot object with the as_ggplot() function from ggpubr:
library(ggpubr)
add_dodged_ticks(your_plot_here, axis = 'bottom') %>% as_ggplot()