Reputation: 13
I'm trying to represent my data by creating a vertical barplot separated by gender.
Ideally, I would like the plot to be vertical, with the same axis for males and females almost like this example:
I try different geom_bar
or geom_histogram
but I am not able to have the same axis...
but I don't understand which value I add in x, or y...
I don't have negative data, instead of "nail polish" etc I have M1, M2 .. with 5 replicate for each.
Upvotes: 0
Views: 142
Reputation: 73692
Considerable easier using base graphics. Just add=
two barplot
s together, in one of them invert the sign using minus `-`()
.
> par(mar=c(5, 4, 4, 1))
> barplot(-df$value[df$sex == 'M'], horiz=TRUE,
+ xlim=replicate(2, max(df$value))*c(-1, 1), xaxt='n', col=4,
+ names.arg=df$type[df$sex == 'M'], las=1, xlab='Revenue in dollars',
+ border=NA)
> b <- barplot(df$value[df$sex == 'F'], horiz=TRUE, add=TRUE, xaxt='n', col=2, border=NA)
> axis(1, axTicks(1), abs(axTicks(1)))
> mtext('Cosmetic sales', line=2.5, cex=1.2)
> legend(-2.5, 6, col=c(4, 2), pch=15, leg=c('Males', 'Females'), bty='n',
+ xpd=TRUE, horiz=TRUE)
Data:
> dput(df)
structure(list(sex = c("M", "M", "M", "M", "F", "F", "F", "F"
), type = c("M1", "M2", "M3", "M4", "M1", "M2", "M3", "M4"),
value = c(6, 7, 5, 5, 4, 6, 4, 4)), class = "data.frame", row.names = c(NA,
-8L))
Upvotes: 0
Reputation: 155
Here is one way to do it:
library(dplyr)
library(ggplot2)
df <- data.frame(sex = c("M", "M", "M", "M", "F", "F", "F", "F"),
type = c("M1", "M1", "M2", "M2", "M1", "M1", "M2", "M2"),
value = c(6,7,5,5,4,6,4,4))
df %>%
mutate(value = if_else(sex == "M", -value, value)) %>%
ggplot(aes(x = value, y = type, fill = sex)) + geom_bar(stat = "summary", fun.data = "mean_se") +
scale_x_continuous(labels = abs)
The idea is basically to convert all values for male to negative achieved by mutate()
you can just generate a bar plot as normal. Since you want it to be horizontal put your discrete categories on the y axis and continuous values on the X axis which is set by the aes()
Finally use scale_x_continuous(labels = abs)
to set all axis labels to absolute value of themselves.
Upvotes: 0
Reputation: 35
Something like this:
## dummy data
dummy.df <- data.frame(Nail.Polish = c(6000, 500),
Rouge = c(3000, 1500),
Soap = c(7000, 3500),
Sex = c("F", "M"))
library(reshape2)
## transform the data.frame into a format for ggplot
dummy.melt <- melt(dummy.df, id.vars = "Sex")
colnames(dummy.melt) <- c("Sex", "Cosmetic", "Value")
## convert one side to negative numbers
dummy.melt$Value[dummy.melt$Sex=="M"] <-
dummy.melt$Value[dummy.melt$Sex=="M"] * -1
library(ggplot2)
## set up the initial plot
g <- ggplot(dummy.melt,
mapping = aes(x = Cosmetic, y = Value, fill = Sex)) +
geom_bar(stat = "identity") +
scale_y_continuous(labels = abs, limits = c(-7500, 7500)) ## using abs() function to convert the scales
## flip the coordinates to make it vertical, add colours, theming etc.
g + coord_flip() +
scale_fill_manual(values = c("orange", "purple")) +
theme_bw() +
theme(panel.grid = element_blank(), aspect.ratio = 1.5)
Upvotes: 0