legend in multiple y-axis plot

Hi,

I am trying to plot a multi y-axis plot. I am not able to get legend for the same. The legend should be according to line type and placed at bottom. I am sharing the data and codes I tried. Additionally I need a similarly plot for Avg_z_score and CR5 vs Year.

Thank you in advance.

code

# z-score and dtd

transform_sec_axis <- function(x) {
  return(x)
}

ggplot(data_plot, aes(year)) +
  geom_line(aes(y = avg_z_score, linetype = "Avg. z-score"), lty = 1, size = 1.1,show.legend = TRUE) +
  geom_line(aes(y = avg_DtD, linetype = "Avg. DtD"), lty = 4, size = 1.1,show.legend = TRUE) +
  scale_y_continuous(
    name = "Avg. z-score",
    breaks = seq(0, 6, by = 1),
    limits = c(0, 6),
    sec.axis = sec_axis(
      name = "Avg. DtD",
      breaks = seq(0, 6, by = 1),
      trans = transform_sec_axis
    )
  ) +
  scale_linetype_manual(name= NULL,values = c("Avg. z-score" = "1", "Avg. DtD" = "4")) +
  theme(legend.position = "bottom",
        axis.title.x = element_blank(),
        legend.title = element_text(),    
        legend.key.width = unit(3, "cm"),
        axis.title.y = element_text(colour = "black", face = "bold"),  # Darken y-axis label
        axis.text.x = element_text(colour = "black", face = "bold"),  # Darken x-axis tick labels
        axis.text.y = element_text(colour = "black", face = "bold"),  # Darken y-axis tick labels
        legend.text = element_text(colour = "black", face = "bold"))  # Darken legend text

Data

   year       CR5  avg_DtD avg_z_score
1  1998 0.4428660 5.168959   2.6226860
2  1999 0.4421126 4.616232   1.7144890
3  2000 0.4282841 4.473966   1.3834157
4  2001 0.4275604 2.966609   1.1534888
5  2002 0.4207379 2.077830   1.5395165
6  2003 0.4149098 1.587460   1.7666254
7  2004 0.4057806 2.363949   2.0271616
8  2005 0.4091860 2.622798   1.3473633
9  2006 0.4098896 2.885536   1.6319377
10 2007 0.4008190 2.976896   1.9266719
11 2008 0.3914018 1.732437   2.1194750
12 2009 0.3907538 2.840667   2.0947765
13 2010 0.3789176 3.025729   1.6967324
14 2011 0.3784298 3.381809   2.1887926
15 2012 0.3747106 3.116533   2.2130639
16 2013 0.3743605 3.462096   1.9223717
17 2014 0.3805648 3.010479   1.6559479
18 2015 0.3866679 2.976423   1.6198978
19 2016 0.3922078 2.314551   1.2656702
20 2017 0.4242170 2.736278   1.1393804
21 2018 0.4514388 2.782183   0.6722697
22 2019 0.4588402 2.394160   0.8211190
23 2020 0.5184670 2.011480   0.9979289
24 2021 0.5124125 2.196324   1.2082861
25 2022 0.5168476 2.655758   1.2650711

@nirgrahamuk please look into this

Would the plot below work for you? I don't see the need for two y axes.

library(ggplot2)
library(tidyr)
data_plot <- read.csv("~/R/Play/Dummy.csv")
data_long <- data_plot |> pivot_longer(col = c("avg_DtD", "avg_z_score"),
                          names_to = "Type", values_to = "Value")
head(data_long)
#> # A tibble: 6 × 4
#>    year   CR5 Type        Value
#>   <int> <dbl> <chr>       <dbl>
#> 1  1998 0.443 avg_DtD      5.17
#> 2  1998 0.443 avg_z_score  2.62
#> 3  1999 0.442 avg_DtD      4.62
#> 4  1999 0.442 avg_z_score  1.71
#> 5  2000 0.428 avg_DtD      4.47
#> 6  2000 0.428 avg_z_score  1.38
ggplot(data_long, aes(x = year, y = Value, linetype = Type)) +
  geom_line(size = 1.1,show.legend = TRUE) +
  scale_y_continuous(
    name = "Value",
    breaks = seq(0, 6, by = 1),
    limits = c(0, 6)
    ) +
  scale_linetype_manual(name= NULL,values = c("avg_z_score" = 1, "avg_DtD" = 4), 
                        labels = c("Avg. DtD", "Avg. z score")) +
  theme(legend.position = "bottom",
        axis.title.x = element_blank(),
        legend.title = element_text(),    
        legend.key.width = unit(3, "cm"),
        axis.title.y = element_text(colour = "black", face = "bold"),  # Darken y-axis label
        axis.text.x = element_text(colour = "black", face = "bold"),  # Darken x-axis tick labels
        axis.text.y = element_text(colour = "black", face = "bold"),  # Darken y-axis tick labels
        legend.text = element_text(colour = "black", face = "bold"))  # Darken legend text
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

Created on 2023-08-28 with reprex v2.0.2

What do you use to read this data into R ?

I copied the posted data into a spreadsheet, where it appears as a single column. I then used the Text To Columns (That's what it is called in OpenOffice. It might have a different name in other software) process to get it in columns and I saved it as a csv.

Thanks for your response. I need the type of plot attached.

If you need to have two y axes, try this:

ggplot(data_plot, aes(x = year)) +
  geom_line(aes(y = avg_z_score, linetype = "avg_z_score"), size = 1.1 ) +
  geom_line(aes(y = avg_DtD, linetype = "avg_DtD"), size = 1.1) +
  scale_y_continuous(
    name = "Avg. z score",
    breaks = seq(0, 6, by = 1),
    limits = c(0, 6),
    sec.axis = sec_axis(
      name = "Avg. DtD",
      breaks = seq(0, 6, by = 1),
      trans = ~.
    )
    ) +
  scale_linetype_manual(name= NULL,values = c("avg_z_score" = 1, "avg_DtD" = 4), 
                        labels = c("Avg. DtD", "Avg. z score")) +
  theme(legend.position = "bottom",
        axis.title.x = element_blank(),
        legend.title = element_text(),    
        legend.key.width = unit(3, "cm"),
        axis.title.y = element_text(colour = "black", face = "bold"),  # Darken y-axis label
        axis.text.x = element_text(colour = "black", face = "bold"),  # Darken x-axis tick labels
        axis.text.y = element_text(colour = "black", face = "bold"),  # Darken y-axis tick labels
        legend.text = element_text(colour = "black", face = "bold"))  # Darken legend text

1 Like

Thanks a lot.
When I plot the graph for avg_z_score and cr5 vs year. I am getting this plot.

ggplot(data_plot, aes(x = year)) +
  geom_line(aes(y = avg_z_score, linetype = "avg_z_score"), size = 1.1 ) +
  geom_line(aes(y = CR5, linetype = "CR5"), size = 1.1) +
  scale_y_continuous(
    name = "Avg. z score",
    breaks = seq(0, 3, by = 1),
    limits = c(0, 3),
    sec.axis = sec_axis(
      name = "CR5",
      breaks = seq(0, 1, by = .25),
      trans = ~.
    )
  ) +
  scale_linetype_manual(name= NULL,values = c("avg_z_score" = 1, "CR5" = 4), 
                        labels = c("Avg. DtD", "CR5")) +
  theme(legend.position = "bottom",
        axis.title.x = element_blank(),
        legend.title = element_text(),    
        legend.key.width = unit(3, "cm"),
        axis.title.y = element_text(colour = "black", face = "bold"),  # Darken y-axis label
        axis.text.x = element_text(colour = "black", face = "bold"),  # Darken x-axis tick labels
        axis.text.y = element_text(colour = "black", face = "bold"),  # Darken y-axis tick labels
        legend.text = element_text(colour = "black", face = "bold"))  # Darken legend text

I think what you want is the code below. Notice that what is plotted for CR5, geom_line(), is 3 times the actual value and that the transformation in sec.axis() divides the labeling by 3. So, the values of CR5 get scaled up to have convenient values on the left plotting axis but the values displayed on the right axis, which labels CR5, show the actual CR5 values.

library(ggplot2)
ggplot(data_plot, aes(x = year)) +
  geom_line(aes(y = avg_z_score, linetype = "avg_z_score"), size = 1.1 ) +
  geom_line(aes(y = CR5*3, linetype = "CR5"), size = 1.1) +
  scale_y_continuous(
    name = "Avg. z score",
    breaks = seq(0, 3, by = 1),
    limits = c(0, 3),
    sec.axis = sec_axis(
      name = "CR5",
      breaks = seq(0, 1, by = .25),
      trans = ~./3
    )
  ) +
  scale_linetype_manual(name= NULL,values = c("avg_z_score" = 1, "CR5" = 4), 
                        labels = c("Avg. DtD", "CR5")) +
  theme(legend.position = "bottom",
        axis.title.x = element_blank(),
        legend.title = element_text(),    
        legend.key.width = unit(3, "cm"),
        axis.title.y = element_text(colour = "black", face = "bold"),  # Darken y-axis label
        axis.text.x = element_text(colour = "black", face = "bold"),  # Darken x-axis tick labels
        axis.text.y = element_text(colour = "black", face = "bold"),  # Darken y-axis tick labels
        legend.text = element_text(colour = "black", face = "bold"))  # Darken legend text

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.