1

I would like to plot bars with several variables and arrange them according to their groups and by ascendant values. To recreate the problem I will use the following example:

df <- data.frame(
  stringsAsFactors = FALSE,
         Country = c("France","Germany","Spain",
                       "Mexico","Colombia","Brasil","China","Vietnam",
                       "Japan"),
                 a = c(272, 172, 301, 245, 270, 284, 281, 294, 225),
                 b = c(640, 398, 689, 603, 619, 654, 616, 632, 430),
                 c = c(1007, 623, 1078, 961, 968, 1024, 951, 971, 635),
                 d = c(1375,849,1467,1318,
                       1317,1394,1285,1310,839),
             Group = c("Group 1","Group 1","Group 1",
                       "Group 2","Group 2","Group 2","Group 3","Group 3",
                       "Group 3"))

#First I arrange my data in the desire order

library(dplyr)
df2 <- df %>% 
  arrange(Group, d) %>%
  mutate(Country = factor(Country, levels = Country),
         Group =factor(Group))

#I created a plot that will be used as a "base"

library(ggplot2)
ggplot(df2, aes(x = Country, y = d , fill = Group))+
  geom_bar(stat="identity",  col = "black")+
  scale_fill_manual(values = c ("blue", "orange", "pink"))+
  ylab("Country")+
  xlab("Values")+
  theme_classic()+
  theme(axis.text.x = element_text(angle = 90, vjust =0.2, hjust = 1))

#that resulted in: 

base plot

#Now comes the problem. I would like to add the rest of the variables (a, b and c) using geom_bar because I would like to add different texture to each column so I coded it this way:

ggplot(df2, aes(x = Country, y = d , fill = Group))+
  geom_bar(position = "dodge", stat="identity",  col = df$Group)+
  geom_bar(df2, aes(x = Country, y = a, fill='blank'))+
  geom_bar(df2, aes(x = Country, y = b, fill= 'hdashes'))+
  geom_bar(df2, aes(x = Country, y = c, fill= 'crosshatch'))+
  scale_fill_manual(values = c ("00028", "gray", "olivedrab1"))+
  ylab("Country")+
  xlab("Values")+
  theme_classic()+
  theme(axis.text.x = element_text(angle = 90, vjust =0.2, hjust = 1))

and R doesn't accept this code.

The following is my desired plot:

desired plot

Any help would be appreciated.

Drop
  • 119
  • 7
  • Try with `geom_bar(data = df2, ....)`. The first argument of a `geom` is the mapping. If you pass the data instead you have to name it. – stefan Jun 22 '21 at 13:07
  • This may help: [How can I add hatches, stripes or another pattern or texture to a barplot in ggplot?](https://stackoverflow.com/q/62393159/13095326) – Ian Campbell Jun 24 '21 at 03:59

1 Answers1

2

You should convert your table as tidy data first.

library(tidyr)
df3 <- pivot_longer(df2, cols = 2:5, names_to = "variable", values_to = "value")

From the data frame that you have provided you will obtain a new data frame with 36 observations and 4 variables. Then in ggplot use geom_col instead. I couldn't add texture to the columns but in alternative you can change the transparency of your columns by adding the aesthetic "alpha".

df3 %>% ggplot(aes(x=Country, y = value)) +
  geom_col(mapping=aes(x=Country, fill= Group, alpha=variable), position = "dodge2")+
  scale_fill_manual(values = c ("blue", "orange", "pink"))+
  scale_alpha_manual(values = c(0.2,0.4,0.6,0.8))+
  ylab("Values")+
  xlab("Country")+
  theme_classic()+
  theme(axis.text.x = element_text(angle = 90, vjust =0.2, hjust = 1))

If you really want to add texture you can look at the answer from @Docconcoct to a similar question here: https://stackoverflow.com/a/20426482/16281137

Tizilys
  • 36
  • 3
  • Please do not attempt the solution recommended by Docconcoct. Instead, use the [ggpattern](https://coolbutuseless.github.io/package/ggpattern/index.html) package. – Ian Campbell Jun 24 '21 at 03:57