ggplot stacked bar chart (proportion) scaled to x variable - r

I need to create a stacked bar chart of the relative proportion, scaled to the x variable. Here's what I mean.
With a dataframe something like this:
df <- data.frame(foo = rep(1:5,500), bar = as.factor(c(rep("a",100), rep("b",100), rep("c",100), rep("d",100), rep("e",100))), baz = c(rep("R", 5*250), rep("CRAN", 5*250)), val = rbinom(5*500,1,0.1))
I need to create a plot that combines the following two plots. I need the shape of the second plot and the bar colour coding of the first plot (scaled to the second plot. Ideally I would also plot a density over it (like the first plot).
library(ggplot2)
ggplot(subset(df, val == 1), aes(x = foo)) + geom_bar(aes(fill = bar), position = "fill") + scale_fill_brewer(type = "div", palette = 8, direction = 1) + facet_wrap(~baz) + geom_density(aes(foo))
ggplot(subset(df, val == 1), aes(x = foo, y = as.factor(foo))) + geom_col(position = "identity") + scale_fill_brewer(type = "div", palette = 8, direction = 1) + facet_wrap(~baz)
The end result should be like the facet on the left (on the image below).
How do I do this in ggplot2?

How about
library(gridExtra)
grid.arrange(p1, p2, ncol=1)
where p1 and p2 are the two ggplots.
p1 <- ggplot(subset(df, val == 1), aes(x = foo)) + geom_bar(aes(fill = bar),
position = "fill") + scale_fill_brewer(type = "div", palette = 8,
direction = 1) + facet_wrap(~baz) + geom_density(aes(foo))
p2 <- ggplot(subset(df, val == 1), aes(x = foo, y = as.factor(foo))) +
geom_col(position = "identity") + scale_fill_brewer(type = "div",
palette = 8, direction = 1) + facet_wrap(~baz)

Maybe something like this would work: In geom_bar() added stat = "identity" and removed fill = "position". And you can replace density with histogram (which is basically the same density).
ggplot(subset(df, val == 1), aes(foo)) +
geom_bar(aes(y = foo, fill = bar), stat = "identity") +
geom_histogram(aes(foo), color = "black") +
facet_wrap( ~ baz) +
scale_fill_brewer(type = "div", palette = 8, direction = 1) +
labs(x = NULL, y = NULL) +
theme(legend.position = "bottom")

This is the solution that I came up with:
df <- data.frame(foo = rep(1:5,500), bar = as.factor(c(rep("a",100), rep ("b",100), rep("c",100), rep("d",100), rep("e",100))), baz = c(rep("R", 5*250), rep("CRAN", 5*250)), val = rbinom(5*500,1,0.1))
p <- ggplot(subset(df, val == 1), aes(x = foo)) + geom_bar(aes(fill = bar), position = "fill") + scale_fill_brewer(type = "div", palette = 8, direction = 1) + facet_wrap(~baz)
p1 <- ggplot(subset(df, val == 1), aes(x = foo, y = as.factor(foo))) + geom_col(position = "identity") + scale_fill_brewer(type = "div", palette = 8, direction = 1) + facet_wrap(~baz)
z <- ggplot_build(p)
z1 <-ggplot_build(p1)
z$data[[1]]$ymin <- z$data[[1]]$ymin*z$data[[1]]$x
z$data[[1]]$ymax <- z$data[[1]]$ymax*z$data[[1]]$x
z$data[[1]]$y <- z$data[[1]]$y*z$data[[1]]$x
z$layout$panel_ranges <- z1$layout$panel_ranges
plot(ggplot_gtable(z))
Here's what it looks like:
This works, but I'm open to other (less hacked together) solutions.

Related

Labeling a point by giving its x and y axes on geom_histogram

How to show the point (x=0, y=1500) with a text label next to it on the following histogram?
ggplot(ds_visits, aes(x = patientsInService)) +
geom_histogram(stat = "count", col = "black", fill = "white") +
theme_bw() +
labs(x = "Patients in service", y = "Cases") +
scale_x_discrete(limits = seq(0, 5, 1))
You have to create dummy data.frame for point data:
pointData <- data.frame(X = 0, Y = 1500)
Plot it with with two additional gems (geom_point and geom_text):
ggplot(ds_visits, aes(patientsInService)) +
geom_histogram(stat = "count", col = "black", fill = "white") +
geom_point(data = pointData, aes(X , Y)) +
geom_text(data = pointData, aes(X + 1 , Y + 10, label = "My Text"))
In geom_text I'm changing coordinates a little bit not to overlap text with point.

How to add labels to each bar in the barplot? [duplicate]

I would like to do a bar plot outlined in black with percentages inside the bars. Is this possible from qplot? I get the percentages to appear but they don't align with the particular bars.
packages: ggplot2, reshape
x <- data.frame(filename = c("file1", "file2", "file3", "file4"),
low = c(-.05,.06,.07,-.14),
hi = c(.87,.98,.56,.79))
x$tot <- x$hi + x$low
x <- melt(x, id = 'filename')
bar <- qplot(x = factor(filename),
y = value*100,
fill = factor(variable),
data = x,
geom = 'bar',
position = 'dodge') + coord_flip()
bar <- bar + scale_fill_manual(name = '',
labels = c('low',
'Hi',
"Tot"),
values = c('#40E0D0',
'#FF6347',
"#C7C7C7"))
bar <- bar + geom_text(aes(label = value*100))+geom_bar(colour = 'black')
bar <- bar + opts(panel.background = theme_rect(colour = NA))
bar <- bar + opts(legend.justification = 'bottom')
print(bar)
Here you go:
library(scales)
ggplot(x, aes(x = filename, fill = variable)) +
geom_bar(stat="identity", ymin=0, aes(y=value, ymax=value), position="dodge") +
geom_text(aes(x=filename, y=value, ymax=value, label=value,
hjust=ifelse(sign(value)>0, 1, 0)),
position = position_dodge(width=1)) +
scale_y_continuous(labels = percent_format()) +
coord_flip()
This would be a good opportunity for you to start moving away from using qplot, in favor of ggplot. This will be much easier in the long run, trust me.
Here's a start:
library(scales)
ggplot(data = x,aes(x = factor(filename),y = value)) +
geom_bar(aes(fill = factor(variable)),colour = "black",position = 'dodge') +
coord_flip() +
scale_fill_manual(name = '',
labels = c('low',
'Hi',
"Tot"),
values = c('#40E0D0',
'#FF6347',
"#C7C7C7")) +
scale_y_continuous(labels = percent_format())
For philosophical reasons, I will leave the annotation piece to you...

Multiple line and bar chart in ggplot with geom_text and colours

I want to combine a line and a bar chart with three different variables using ggplot. The bar chart should have the values on top and should be filled with the same colours as the lines in the chart above. Here is my code
# First some data generation
df.x = data.frame(date = Sys.Date()-20:1,
value = c(1:20),
variable = "line",
object = "x")
df.y = data.frame(date = Sys.Date()-20:1,
value = c(1:20)*2,
variable = "line",
object = "y")
df.z = data.frame(date = Sys.Date()-20:1,
value = c(1:20)*3,
variable = "line",
object = "z")
df.y.bar = data.frame(date = Sys.Date()-10,
value = 30,
variable = "bar",
object = "y")
df.x.bar = data.frame(date = Sys.Date()-10,
value = 40,
variable = "bar",
object = "x")
df.z.bar = data.frame(date = Sys.Date()-10,
value = 50,
variable = "bar",
object = "z")
df = rbind(df.x, df.y,df.z, df.x.bar, df.y.bar,df.z.bar)
my.cols = c("blue", "green", "yellow")
# Pass everything to ggplot
ggplot(df, aes_string(x = "date", y = "value", fill="variable")) +
facet_grid(variable~., scales="free_y") +
geom_line(data = subset(df, variable == "line"), aes(colour = factor(object)), size = 1, show_guide = FALSE, stat="identity") +
geom_bar(data = subset(df, variable == "bar"), aes(colour = factor(object)), show_guide = TRUE, stat="identity", position = "dodge") +
geom_text(data = subset(df, variable == "bar"), aes(y=value+0.7 * sign(value), ymax=value, label=round(value, 2)), position = position_dodge(width = 0.9), size=3) +
scale_colour_manual(values = my.cols)
The resulting plot is not exactly what I wanted. I used position_dodge(width = 0.9) but the text over the bars does not move. Irretatingly this does not happen when I only chose two variable (e.g. x and y) to be included in the data frame. The desired result should look like this:
Thanks a lot for your help!
You can fill the bars by choosing fill = factor(object) and adding scale_fill_manual(values = my.cols).
In order to have only one legend I think removing fill="variable" from aes_string did the trick in combination with scale_fill_manual.
And for dodging the text you need to add a group argument and position = position_dodge(width=1)
ggplot(df, aes_string(x = "date", y = "value")) +
facet_grid(variable~., scales="free_y") +
geom_line(data = subset(df, variable == "line"), aes(colour = factor(object)), size = 1, show_guide = FALSE, stat="identity") +
geom_bar(data = subset(df, variable == "bar"), aes(fill = factor(object)), show_guide = TRUE, stat="identity", position = "dodge") +
geom_text(data =subset(df, variable == "bar"), aes(x=date, y=(value+0.7) * sign(value), ymax=value, label=round(value, 2), group=object), position = position_dodge(width=1), size=3) +
scale_colour_manual(values = my.cols) +
scale_fill_manual(values = my.cols)

R ggplot placing labels on error bars

I can create a bar chart with error bars but how can I put labels on the higher (vLABELH) and lower error bars (vLABELL).
library(ggplot2)
vx <- c(1:5)
vBAR <- c(0.1,0.2,0.3,0.4,0.5)
vLINE1 <- c(0.15,0.25,0.35,0.45,0.55)
vLINE2 <- c(0.15,0.25,0.35,0.45,0.55)
vLINE3 <- c(0.05,0.15,0.25,0.35,0.45)
vLABELL<- c(0.05,0.15,0.25,0.35,0.45)
vLABELH <- c(0.15,0.25,0.35,0.45,0.55)
df1 <- as.data.frame(cbind(vx,vBAR,vLINE1,vLINE2,vLINE3,vLABELL,vLABELH))
class(df1)
barchart1 <- ggplot(df1, aes(x=as.factor(vx),y=vBAR)) + geom_bar(fill="blue", colour="blue")+
geom_errorbar(aes(ymin=vLINE3, ymax=vLINE1 ))
barchart1
I suppose you're looking for geom_text.
ggplot(df1, aes(x = as.factor(vx), y = vBAR)) +
geom_bar(stat = "identity", fill = "blue", colour = "blue") +
geom_errorbar(aes(ymin = vLINE3, ymax = vLINE1 )) +
geom_text(aes(label = vLABELH, y = vLINE1), vjust = -.5) +
geom_text(aes(label = vLABELL, y = vLINE3), vjust = 1.5)

Adding labels to ggplot bar chart

I would like to do a bar plot outlined in black with percentages inside the bars. Is this possible from qplot? I get the percentages to appear but they don't align with the particular bars.
packages: ggplot2, reshape
x <- data.frame(filename = c("file1", "file2", "file3", "file4"),
low = c(-.05,.06,.07,-.14),
hi = c(.87,.98,.56,.79))
x$tot <- x$hi + x$low
x <- melt(x, id = 'filename')
bar <- qplot(x = factor(filename),
y = value*100,
fill = factor(variable),
data = x,
geom = 'bar',
position = 'dodge') + coord_flip()
bar <- bar + scale_fill_manual(name = '',
labels = c('low',
'Hi',
"Tot"),
values = c('#40E0D0',
'#FF6347',
"#C7C7C7"))
bar <- bar + geom_text(aes(label = value*100))+geom_bar(colour = 'black')
bar <- bar + opts(panel.background = theme_rect(colour = NA))
bar <- bar + opts(legend.justification = 'bottom')
print(bar)
Here you go:
library(scales)
ggplot(x, aes(x = filename, fill = variable)) +
geom_bar(stat="identity", ymin=0, aes(y=value, ymax=value), position="dodge") +
geom_text(aes(x=filename, y=value, ymax=value, label=value,
hjust=ifelse(sign(value)>0, 1, 0)),
position = position_dodge(width=1)) +
scale_y_continuous(labels = percent_format()) +
coord_flip()
This would be a good opportunity for you to start moving away from using qplot, in favor of ggplot. This will be much easier in the long run, trust me.
Here's a start:
library(scales)
ggplot(data = x,aes(x = factor(filename),y = value)) +
geom_bar(aes(fill = factor(variable)),colour = "black",position = 'dodge') +
coord_flip() +
scale_fill_manual(name = '',
labels = c('low',
'Hi',
"Tot"),
values = c('#40E0D0',
'#FF6347',
"#C7C7C7")) +
scale_y_continuous(labels = percent_format())
For philosophical reasons, I will leave the annotation piece to you...

Resources