Home > Blockchain >  How to costumize bar chart in ggplot R?
How to costumize bar chart in ggplot R?

Time:05-03

I have a mirrored bar-chart, and I want avoid mirror bars and have the same graphs but 2 columns for each category:

  1. Negative and positive (firstly positive values on right side and below negative values on left side)
  2. Colours must be determined by 'Model' categorical variable and pos & neg values need to be different, like fully coloured bars = positive, bounded (with the same colour) but not filled bars = negative.
  3. Also, USA based values must be on the top and Canada based values below
df <- data.frame (Origin = c("Canada", "Canada","Canada", "Canada","Canada", "Canada","USA","USA","USA","USA","USA","USA"),
                  Model = c("A","B","C","D","E","F","A","B","C","D","E","F"),
                  poschange = c(60, 45,34,56, 65, 44,40, 55, 35, 24,34,12),
                  negchange = c(-5,-2,-0.5,-2,-1,-0.05,-1,-3,-0.1,-3,-1.5,-0.9))

require(dplyr)
require(ggplot2)
require(tidyr)


df2 <- df %>% pivot_longer(., cols=c('poschange','negchange'),
                           names_to = 'value_category')
df2 <- df2 %>% mutate(Groups = paste(Origin, Model))
df2 <- df2 %>% mutate(label_position=ifelse(value>0, value-5,value-8)) # adjusting label position
df2 %>% arrange(value) %>% ggplot(aes(x=value, y=reorder(Groups,value), 
                                      fill=value_category, 
                                      group=value_category)) 
  geom_col(width=0.75)
coord_flip()

Output: enter image description here

Desired output (something like this but colours must be corresponding to Model cat. variable):

enter image description here

CodePudding user response:

Maybe something like this?

  1. Use an ifelse statement to label the negative values as "white"
  2. To have a fill of white, use scale_fill_manual with a my_color palette
  3. To avoid "mirrored" bars, use position = "dodge"
  4. To have negative and positive values side-by-side, you need to swap your x and y argument in ggplot
  5. To avoid overlapping text on the x-axis, use theme(axis.text.x = element_text(angle = 90))
  6. Use the breaks argument in both scale_xxx_manual function to remove the "white" label in the legend
library(tidyverse)
df <- data.frame (Origin = c("Canada", "Canada","Canada", "Canada","Canada", "Canada","USA","USA","USA","USA","USA","USA"),
                  Model = c("A","B","C","D","E","F","A","B","C","D","E","F"),
                  poschange = c(60, 45,34,56, 65, 44,40, 55, 35, 24,34,12),
                  negchange = c(-5,-2,-0.5,-2,-1,-0.05,-1,-3,-0.1,-3,-1.5,-0.9))

df2 <- df %>% pivot_longer(., cols=c('poschange','negchange'),
                           names_to = 'value_category') %>% 
  mutate(Groups = paste(Origin, Model),
         value_category = factor(value_category, levels = c("negchange", "poschange")))

my_color = c("A" = '#7fc97f', "B" = '#beaed4', "C" = '#fdc086', 
             "D" = '#ffff99', "E" = '#386cb0', "F" = '#f0027f', "white" = "white")

ggplot(df2, aes(value, Model, 
                fill = ifelse(value_category == "negchange", "white", Model), 
                color = Model))   
  geom_col(position = "dodge")  
  scale_fill_manual(values = my_color, breaks = df2$Model)  
  scale_color_manual(values = my_color, breaks = df2$Model)  
  labs(fill = "Model")  
  facet_grid(Origin ~ ., switch = "y")  
  theme(axis.text.x = element_text(angle = 90),
        strip.background = element_rect(fill = "white"),
        strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0),
        panel.spacing = unit(0, "lines"))

Created on 2022-05-03 by the reprex package (v2.0.1)

CodePudding user response:

require(ggplot2)
require(dplyr)
require(tidyr)

df <- data.frame (Origin = c("Canada", "Canada","Canada", "Canada","Canada", "Canada","USA","USA","USA","USA","USA","USA"),
                  Model = c("A","B","C","D","E","F","A","B","C","D","E","F"),
                  poschange = c(60, 45,34,56, 65, 44,40, 55, 35, 24,34,12),
                  negchange = c(-5,-2,-0.5,-2,-1,-0.05,-1,-3,-0.1,-3,-1.5,-0.9))
df2 <- df %>% pivot_longer(., cols=c('poschange','negchange'),
                           names_to = 'value_category')
df2 <- df2 %>% mutate(Groups = paste(Origin, Model))
df2 <- df2 %>% mutate(label_position=ifelse(value>0, value-5,value-8)) # adjusting label position
df2 %>% arrange(value) %>% 
  ggplot(aes(x=Groups, y=value, fill=Model,group=value_category)) 
  geom_col(width=0.75,position='dodge')   # or geom_bar(stat='identity')
  coord_flip()  
  labs(x='Groups', y='Value')

Created on 2022-05-03 by the reprex package (v2.0.1)

  • Related