user18937485
user18937485

Reputation:

How to build barchart with dual axis in ggplot R?

I want to plot barchart with dual axis, where 'cost' variable is reflected on the right y-axis. After I specified sec.axis = sec_axis(~.*2, name ="Cost") however as it seems, the curve is not adjusted according to axis on right

df <- data.frame (model  = c("A", "B", "C","D","E","F"),
                  share = c(12,20,15,9,60,20),
                  sale = c(16,25,18,14,67,28),
                  cost = c(14,19,28,24,57,28))

#set levels of model by cost
df$model <- factor(df$model, levels = arrange(df, desc(df$cost))$model)

library(tidyverse)

df_long <- df %>% 
  pivot_longer(
    cols = -model
  ) 


plt <- ggplot(df_long, aes(x = model, y= value, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=name), position = position_dodge())+
  scale_fill_manual(values = c("blue", "grey"))+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name, group = 1), size = 1)+
  scale_color_manual(values = "red")+
  geom_text(data = filter(df_long, name == "cost"), size = 3,hjust=0, vjust=-0.5)+
  #geom_label(data = filter(df_long, name == "cost"), hjust=0, vjust=-0.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~.*2, name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())


plt

enter image description here

Upvotes: 0

Views: 84

Answers (1)

TarJae
TarJae

Reputation: 78927

Update: We have to adapt y=value/2 in geom_line(): However this will cause another issue with geom_text()

plt <- ggplot(df_long, aes(x = model, y=value, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=name), position = position_dodge())+
  scale_fill_manual(values = c("blue", "grey"))+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name,  y= value/2, group = 1), size = 1)+
  scale_color_manual(values = "red")+
  geom_text(data = filter(df_long, name == "cost"), size = 3,hjust=0, vjust=5)+
  #geom_label(data = filter(df_long, name == "cost"), hjust=0, vjust=-0.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~.*2, name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())


plt

enter image description here

you have to devide y by the same you multiple in sec.axis. In your case: y= value/2

If you want to automate:

coeff <- 2

plt <- ggplot(df_long, aes(x = model, y= value/coeff, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=name), position = position_dodge())+
  scale_fill_manual(values = c("blue", "grey"))+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name, group = 1), size = 1)+
  scale_color_manual(values = "red")+
  geom_text(data = filter(df_long, name == "cost"), size = 3,hjust=0, vjust=-0.5)+
  #geom_label(data = filter(df_long, name == "cost"), hjust=0, vjust=-0.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~.*coeff, name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())


plt

enter image description here

Upvotes: 1

Related Questions