Home > Back-end >  R: How to build barplot with multiple bars and dual axis?
R: How to build barplot with multiple bars and dual axis?

Time:06-04

my dataframe has 1 categorical and 3 numerical variables. I want to build barplot in plotly R, where 'share' and 'sale' variables will be given in bars and reflected on left y axis while 'cost' variable will be visualized by line and units will be reflected on second axis on right. In addition colour of bars should be different according to 'model' column

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))

Expected output (enter image description here

CodePudding user response:

Update2: Just to show how vjust works:

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 = 2) 
  scale_color_manual(values = "red") 
  geom_point(data = filter(df_long, name == "cost"), size = 2) 
  geom_text(data = filter(df_long, name == "cost"), hjust=0, vjust=-6) 
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~., name ="Cost")
  ) 
  theme_minimal() 
  theme(legend.title=element_blank())

enter image description here

Update with secondary y axis and numbers for the points:

library(tidyverse)

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


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 = 2) 
  scale_color_manual(values = "red") 
  geom_point(data = filter(df_long, name == "cost"), size = 2) 
  geom_text(data = filter(df_long, name == "cost"), hjust=0, vjust=0) 
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~., name ="Cost")
  ) 
  theme_minimal() 
  theme(legend.title=element_blank())

enter image description here

First answer: Something like this?

  1. Bring your data in long format

  2. for each bar and line filter the data

library(tidyverse)

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


ggplot()  
  geom_col(data = filter(df_long, name != "cost"), aes(x = model, y= value, fill=name), position = position_dodge()) 
  scale_fill_manual(values = c("blue", "grey")) 
  geom_line(data = filter(df_long, name == "cost"), aes(x = model, y= value, color=name, group=1), size = 2) 
  geom_point(data = filter(df_long, name == "cost"), aes(x = model, y= value), size = 2) 
  scale_color_manual(values = "red") 
  theme_minimal() 
  theme(legend.title=element_blank())

enter image description here

  • Related