There is a solution that doesn’t make another axis but manipulates the labels on the second axis as HTML using the ggtext package.
First you find the coefficients to rebase the other 2 variables.
## Packages
library(ggtext);library(tidyverse)
## Data
df <- data.frame(category = paste0(rep("type_", 30), c("A", "B", "C")),
x_val = rep(1:10, 3), y_val = abs(rnorm(30))*c(100,10,1))
## Rebase
rebase_coef <- df %>% group_by(category) %>% summarise(rebase_coef = max(y_val)) %>%
ungroup() %>% mutate(rebase_coef = rebase_coef / max(rebase_coef))
df_rebase <- df %>%
mutate(y_val = case_when(category == "type_B" ~ y_val/rebase_coef$rebase_coef[2],
category == "type_C" ~ y_val/rebase_coef$rebase_coef[3],
TRUE ~ y_val))
Then, create a data frame that will make your labels from a vector that will e used as the primary axis breaks (I use a function that easily converts labels into HTML):
## Y Axis Breaks
vbreaks <- max(df$y_val)*c(1, 0.75, 0.5, 0.25, 0)
## Category colors
vcolor_cat <- c("#0077B7","#8B4500","#4DAF4A"); names(vcolor_cat) <- unique(df$category)
## HTML function
html_fun <- function(x, color = 'white', size = 12) {
paste0("<span style = 'color:", color,";font-size:", size, "pt'><b>", x, "</b></span>")
}
## 2nd Labels
axis_labs <- data.frame(y_A = vbreaks, y_B = vbreaks/10, y_C = vbreaks/100) %>%
mutate(ylab_txt = paste0(html_fun(round(y_B,2), color = vcolor_cat[2]), "<br>",
html_fun(round(y_C,2), color = vcolor_cat[3]) ))
Then you plot:
df_rebase %>% ggplot(aes(x = x_val, y = y_val, color = category)) + geom_point() +
scale_color_manual(values = vcolor_cat) +
scale_y_continuous(breaks = vbreaks, labels = function(x) round(x, 2), name = "1 Thing",
sec.axis = sec_axis(~.*1, labels = axis_labs$ylab_txt, breaks = vbreaks, name = "2 Things")) +
theme(
axis.title.y.left = element_textbox_simple(
hjust = 0.5, vjust = 0.5, halign = 0.5, valign = 0.5,
orientation = "left-rotated", width = 0.75, fill = "grey90",
padding = margin(4, 2, 3, 2), margin = margin(2, 2, 2, 0)),
axis.title.y.right = element_textbox_simple(
hjust = 0.5, vjust = 0.5, halign = 0.5, valign = 0.5,
orientation = "right-rotated", width = 0.75, fill = "grey90",
padding = margin(4, 2, 3, 2), margin = margin(2, 0, 2, 2)),
axis.text.y.left = element_markdown(
colour = vcol_metric[1], fill = 'transparent', size = 12, face = "bold",
hjust = 1, vjust = 0.5, halign = 1, valign = 0.5, lineheight = 0.75,
padding = ggplot2::margin(3, 1, 1, 1), margin = ggplot2::margin(0, 0, 0, 0),
align_widths = FALSE, align_heights = FALSE
),
axis.text.y.right = element_markdown(
fill = 'transparent', hjust = 0, vjust = 0.5, halign = 0, valign = 0.5, lineheight = 0.75,
padding = ggplot2::margin(3, 1, 1, 1), margin = ggplot2::margin(0, 0, 0, 0),
align_widths = FALSE, align_heights = FALSE
))
3 Y-Axis Plot
dput(data)? So we can help you better