R ggplot placing labels on error bars - r

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)

Related

Adding legend to bar chart with data from two data frames

I have two plots I just want to know how I can add a legend for the blue and gray bar charts and also could you please show me how you could also edit the legend tittle.
X1 <- c(seq(7.912087912,44.83516484,1.538461538))
X2 <- c(seq(7.912087912,49.45054945,1.538461538))
dat2 <- data.frame(x = X2 , y = rnorm(28, 26, 5))
dat1 <- data.frame(x = X1 , y = rnorm(100, 25, 4))
ggplot(NULL) +
geom_bar(dat1, mapping = aes(x = x, y = y), stat = "identity",alpha = 0.3, position = "stack" ) + labs( x = " Time [ S ]", y = "Frequency") + theme_minimal() +
ggtitle("Histogram Of Time In Tank") + theme(plot.title = element_text(hjust = 0.5)) +
theme(plot.title = element_text(hjust = 0.5)) +
geom_bar(dat2, mapping = aes(x = x, y = y ), stat = "identity", alpha = .3, position = "stack", fill='lightblue' , color='lightblue4')
+ scale_linetype_discrete(name = LegendTitle)
If you want a legend in ggplot, you need to have an aesthetic mapping inside your aes() or no legend will appear. Here's how we can set a mapping and then use the scale to set the colors we want
ggplot(NULL) +
geom_bar(dat1, mapping = aes(x = x, y = y, fill="Grey Bars"), stat = "identity",alpha = 0.3, position = "stack" ) +
labs( x = " Time [ S ]", y = "Frequency") +
theme_minimal() +
ggtitle("Histogram Of Time In Tank") +
theme(plot.title = element_text(hjust = 0.5)) +
geom_bar(dat2, mapping = aes(x = x, y = y, fill='Blue Bars') , stat = "identity", alpha = .3, position = "stack", color='lightblue4') +
scale_fill_manual(name="Bars", values=c("Grey Bars" = "grey35", "Blue Bars" = "lightblue"))

ggplot stacked bar chart (proportion) scaled to x variable

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.

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.

showing scale_fill_manual from scratch

I want to show histograms of multiple groups where the values do not stack. I do this by:
dat <- data.frame(x = seq(-3, 3, length = 20))
dat$y <- dnorm(dat$x)
dat$z <- dnorm(dat$x, mean = 2)
p <- ggplot(dat, aes(x = x)) +
geom_bar(aes(y = y), stat = "identity", alpha = .5, fill = "red") +
geom_bar(aes(y = z), stat = "identity", alpha = .5, fill = "blue")
I'd like to have a fill legend that shows the groupings. I'm not sure why this does not produce any legend (or error):
p + scale_fill_manual(values = c(x = "red", z = "blue"),
limits = c("mean 0", "mean 2")) +
guides(fill=guide_legend(title.position="top"))
Using unnamed values produces the same result.
Thanks,
Max
The legend is automatically generated only if you map fill to variable using aes, like so:
library(reshape2)
ggplot(melt(dat, "x"), aes(x = x)) +
geom_bar(aes(y = value, fill = variable),
stat = "identity", position = "identity", alpha = .5) +
scale_fill_manual(values = c(y = "red", z = "blue"),
labels = c("mean 0", "mean 2"))

"Density" curve overlay on histogram where vertical axis is frequency (aka count) or relative frequency?

Is there a method to overlay something analogous to a density curve when the vertical axis is frequency or relative frequency? (Not an actual density function, since the area need not integrate to 1.) The following question is similar:
ggplot2: histogram with normal curve, and the user self-answers with the idea to scale ..count.. inside of geom_density(). However this seems unusual.
The following code produces an overinflated "density" line.
df1 <- data.frame(v = rnorm(164, mean = 9, sd = 1.5))
b1 <- seq(4.5, 12, by = 0.1)
hist.1a <- ggplot(df1, aes(v)) +
stat_bin(aes(y = ..count..), color = "black", fill = "blue",
breaks = b1) +
geom_density(aes(y = ..count..))
hist.1a
#joran's response/comment got me thinking about what the appropriate scaling factor would be. For posterity's sake, here's the result.
When Vertical Axis is Frequency (aka Count)
Thus, the scaling factor for a vertical axis measured in bin counts is
In this case, with N = 164 and the bin width as 0.1, the aesthetic for y in the smoothed line should be:
y = ..density..*(164 * 0.1)
Thus the following code produces a "density" line scaled for a histogram measured in frequency (aka count).
df1 <- data.frame(v = rnorm(164, mean = 9, sd = 1.5))
b1 <- seq(4.5, 12, by = 0.1)
hist.1a <- ggplot(df1, aes(x = v)) +
geom_histogram(aes(y = ..count..), breaks = b1,
fill = "blue", color = "black") +
geom_density(aes(y = ..density..*(164*0.1)))
hist.1a
When Vertical Axis is Relative Frequency
Using the above, we could write
hist.1b <- ggplot(df1, aes(x = v)) +
geom_histogram(aes(y = ..count../164), breaks = b1,
fill = "blue", color = "black") +
geom_density(aes(y = ..density..*(0.1)))
hist.1b
When Vertical Axis is Density
hist.1c <- ggplot(df1, aes(x = v)) +
geom_histogram(aes(y = ..density..), breaks = b1,
fill = "blue", color = "black") +
geom_density(aes(y = ..density..))
hist.1c
Try this instead:
ggplot(df1,aes(x = v)) +
geom_histogram(aes(y = ..ncount..)) +
geom_density(aes(y = ..scaled..))
library(ggplot2)
smoothedHistogram <- function(dat, y, bins=30, xlabel = y, ...){
gg <- ggplot(dat, aes_string(y)) +
geom_histogram(bins=bins, center = 0.5, stat="bin",
fill = I("midnightblue"), color = "#E07102", alpha=0.8)
gg_build <- ggplot_build(gg)
area <- sum(with(gg_build[["data"]][[1]], y*(xmax - xmin)))
gg <- gg +
stat_density(aes(y=..density..*area),
color="#BCBD22", size=2, geom="line", ...)
gg$layers <- gg$layers[2:1]
gg + xlab(xlabel) +
theme_bw() + theme(axis.title = element_text(size = 16),
axis.text = element_text(size = 12))
}
dat <- data.frame(x = rnorm(10000))
smoothedHistogram(dat, "x")

Resources