Reputation: 2536
I have 2 plots that I'm joining together. The top shows the raw data and the second is a subjective rating. The issue is that when I try to have a label using annotate() with rich text explaining what the ratings are, everything gets shifted. However, when I use annotate() with regular text, I don't get this issue. However, in my real use case, I need the richtext because I need the label to have multiple colors. Having multiple annotates() each with their own color is unruly because the text easily gets shifted.
Why is this happening and is there a way to fix it? I want the plot to look like the second image but with FAST and SLOW in color.
library(ggplot2)
library(ggtext)
library(dplyr)
library(patchwork)
#sample data; basic tidying to resemble my real data, no help needed here
car_data <- mtcars %>%
mutate(gear_fct = factor(gear), ordered = is.ordered(gear)) %>%
group_by(gear_fct) %>%
dplyr::summarize(avg_hp = mean(hp)) %>%
mutate(power = if_else(avg_hp >= 100, "Fast", "Slow"))
#make base plot, no help needed here
plot <- car_data %>%
ggplot(aes(x = gear_fct, y = avg_hp)) +
geom_col()
#Make labels to go below the plot
table_plot <- ggplot(car_data, aes(x = gear_fct, y = 1)) +
geom_text(aes(label = power), size = 2.5, fontface = "bold", nudge_x = 0) +
annotate("richtext", label = "Rating<br>(<span style='color:#87B8C5;'>FAST</span> or <span style='color:#BD8A8B;'>SLOW</span>):",
x = 0, y = 1, size = 2, fontface = "bold", hjust = -.5,
fill = NA, label.color = NA) +
theme_void() +
theme(axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
plot.margin = margin(0, 0, 0, 0))
#join plots together
combined_plot <- plot / table_plot + plot_layout(heights = c(3, 0.5))
combined_plot
That code produces this plot; note the shifting and that the ratings aren't underneath the axis.
But, if I switch out the annotate in the above code with:
annotate("text", label = "Rating\n(FAST or SLOW):",
x = .65, y = 1, size = 1, fontface = "bold") +
Then I get a plot that looks exactly how I want it, but the FAST and SLOW aren't in color, which I need:
Upvotes: 0
Views: 52
Reputation: 66880
add
coord_cartesian(xlim = c(1, 3), clip = "off") +
I think the issue is that ggplot is treating the "text" annotation as separate from the data, so it does not influence the range of the table_plot
x axis, but it does treat the "richtext" annotation as data that should be sized around. Arguably a bug, but I don't know enough about how ggplot2 should treat extension-package geom's as annotations.
To get around it, you could manually specify the range of data. In this case you have three factor levels, so xlim = c(1,3)
will set the limits accordingly, and clip = "off"
will prevent clipping of data beyond the axis range.
To get the "Rating" part centered, use x = 0.5, y = 1, size = 2, fontface = "bold", hjust = 0.5,
.
Upvotes: 1