Search code examples
rggplot2bar-chartaxis-labels

R: plotting grouped bar plots without intermittent colors


Given this dataframe df:

City             P1     P2
A                11.7   NA
B                7.5    0.0
C                6.3    0.2
D                5.6    0.1
E                4.5    0.2
F                3.9    0.1
G                3.4    0.3
H                2.7    0.0
I                2.2    0.1
J                1.8    0.3
K                1.5    0.4
L                0.9    0.2
M                0.8    0.1

I want to produce a grouped barplot where the P1 values are grouped together, and the P2 values are grouped together. Also, I want each group of bars to have the same color - P1 in blue, P2 in red - as in this mock-up: enter image description here

My attempt produces some sort of freak, and an error:

barplot(cbind(df$P1,df$P2), main="Grouped barplots", 
ylab="%", beside=TRUE, col=c("blue","red"),ylim=c(0,12),names.arg=df$City,las=2)
legend(13, 10, c("P1","P2"), cex=0.88, fill=c("blue","red"))



Error in barplot.default(cbind(df$P1, df$P2), : incorrect number of names
Traceback:

1. barplot(cbind(df$P1, df$P2), 
 .     main = "Grouped barplots", 
 .     ylab = "%", beside = TRUE, col = c("blue", "red"), ylim = c(0, 
 .         12), names.arg = df$City, las = 2)
2. barplot.default(cbind(df$P1, df$P2), 
 .     main = "Grouped barplots", 
 .     ylab = "%", beside = TRUE, col = c("blue", "red"), ylim = c(0, 
 .         12), names.arg = df$City, las = 2)
3. stop("incorrect number of names")

enter image description here

So, I end up with intermittent colors (blue-red-blue,...), the axes and title are gone, and I cannot read the labels. What am I doing wrong?


Solution

  • Not sure if you'd like to stay away from base graphics, but in any case, here's ggplot example.

    I've mocked up some data too.

    Here's the mock data:

        > dt <- data.table(City = LETTERS[1:10], P1 = sample(1:10, 10, replace = TRUE), P2 = sample(10:20, 10, replace = TRUE))
    > dt
        City P1 P2
     1:    A  1 14
     2:    B  5 18
     3:    C  8 12
     4:    D  2 16
     5:    E  6 15
     6:    F 10 14
     7:    G  5 19
     8:    H  2 11
     9:    I  6 20
    10:    J  4 19
    

    Here's the code:

    dt_m <- melt(dt, id.vars = "City")
    
    g <- ggplot(data = dt_m)
    g <- g + geom_col(aes(x = City, y = value, fill = as.factor(variable)))
    g <- g + scale_fill_manual(values = c("blue", "red"), labels = c("P1", "P2"))
    g <- g + labs(fill = "your variable")
    g <- g + facet_wrap(~variable)
    g
    

    enter image description here

    Is this what you are after?