FaCoffee
FaCoffee

Reputation: 7929

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?

Upvotes: 0

Views: 180

Answers (2)

mpalanco
mpalanco

Reputation: 13570

Combining both plots using base graphics (used by the OP):

# Data
library(data.table)
set.seed(1)
dt <- data.table(City = LETTERS[1:10], P1 = sample(1:10, 10, replace = TRUE), P2 = sample(10:20, 10, replace = TRUE))

# Plots
par(mfrow = c(1, 2))
barplot(dt$P1, main = "P1", col = "blue", ylim = c(0, 20), names.arg = dt$City, las = 1, cex.axis =  1)
barplot(dt$P2, main = "P2", col = "red", ylim = c(0, 20), names.arg = dt$City, las = 1, cex.axis =  1)

Output

enter image description here

Upvotes: 1

Gin_Salmon
Gin_Salmon

Reputation: 847

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?

Upvotes: 1

Related Questions