add different colour to bar plot - r

I constructed the following plot using ggplot using the following code:
ggplot(data, aes(x=Variable, y=Value, fill=Yield.Type)) +
geom_bar(stat="identity", position="dodge")
I had two questions:
1) How do I change the colour of the bar: I want to colour the pink bar as white and blue bar as grey with black borders. If in the code, I use col="White",fill="White", it colours both of them with the same colour and also stacks them up on each other
2) For each bar, I have the standard error in separate vector
For pink bars, se1<-c(0.08,0.07,0.08,0.07)
For blue bars, se2<-c(0.07,0.1,0.06,0.06)
I wanted to know how to add this standard errors to resepctive batch
How do I add this to the bar?

Please provide data it is much easier to answer. Here I have created a new set.
I have included martin's answer for the color
If you have a se value per bar, your should directly add it inside your data frame and use
geom_errorbar(). Check documentation for more info.
.
Variable <- factor(c("VAr1","VAr1","Var2","Var2","Var3","Var3","VAr4","VAr4"))
Yield.Type <- factor(c('O','R','O','R','O','R','O','R'))
Value <- c(1,2,3,4,3,5,6,5)
se1<-c(0.08,0.07,0.08,0.07,0.1,0.06,0.1,1)
data <- data.frame(Variable,Yield.Type,Value,se1)
limits <- aes(ymax = Value + se1, ymin=Value - se1)
dodge <- position_dodge(width=0.8)
ggplot(data, aes(x=Variable, y=Value,fill=Yield.Type,colour=Yield.Type)) +
geom_bar(stat="identity", position="dodge")+
scale_color_manual(values=c("black","black")) +
scale_fill_manual(values=c("white", "grey"))+
geom_errorbar(limits, position=dodge,width=0.1)

First question: use scale_color_manual and scale_fill_manual (see add different colour to bar plot)
p <- ggplot(...)
p + scale_color_manual(values=c("white","black")) +
scale_fill_manual(values=c("white", "grey"))
p
Second qestion: Look here or R: ggplot2 barplot and error bar for help.

Related

Adding reference points and lines to a geom_line() plot

I have a data frame like `dat1:
dat1 <- data.frame(idx = 1:200,
fit = rnorm(200,10,0.5))
cis <- data.frame(uci=dat1$fit+0.5,
lci = dat1$fit-0.5)
dat1 <- cbind(dat1,cis)
I also have 3 other objects where I have stored "points of interest" (or poi1:3) for dat1.
poi1 <- c(30,59,120,150)
poi2 <- c(10,42,110,165,190)
poi3 <- c(50, 100)
I made a line plot with confidence bands for dat1 using this code:
p<-
ggplot(dat1, aes(x=idx, y=fit))+
geom_line()+
geom_ribbon(aes(ymin = lci, ymax = uci), alpha = 0.3)+
labs(x="Distance", y="Var1")
p
I want to highlight the "points of interest" along this line. I want to highlight the points for poi1 red, the points for poi2 blue, and the points for poi3 green. I can use geom_vline() to make them all vertical:
p+
geom_vline(xintercept =poi1, color="red")+
geom_vline(xintercept = poi2, color = "blue")+
geom_vline(xintercept = poi3, color = "green")
But I would actually like the points for poi1 and poi2 to be either blue and red points (instead of lines, and leaving poi3 as a vertical green line), or much "shorter" versions of what is done by geom_vline (both above and below the black line). I cannot get geom_point() to behave correctly and do this. Do I need to format it differently, or how can I accomplish this?
Also, how can I next add a legend in the top corner that denotes which line/point and color denotes which group of poi? For instance if they are points (plus the green line) it will have a red point and say "poi1" a blue point next to the word "poi2" and a small green line next to the work "poi3"
Probably the most straightforward way to add the colored points is to have separate calls to geom_point and supply poi1, poi2, and poi3 as the method to subset your plot.
So, the code would look something like this:
p +
geom_point(data=dat1[which(dat1$idx %in% poi1),], color='red', size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi2),], color='blue', size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi3),], color='green', size=3)
The one problem here is that there's no reference to what those colors are supposed to be (as in... a legend). If you want to add that, you would put color= within aes(...) so that a legend key is created, and assign the name of the key item within (e.g. aes(color="name of item 1")). Then you would need a scale_color_manual(...) call to set the colors specifically... or you can do without the scale_color_manual object and just leave it up to ggplot to figure out the color scheme.
Assigning the colors manually in legend:
p +
geom_point(data=dat1[which(dat1$idx %in% poi1),], aes(color='poi1'), size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi2),], aes(color='poi2'), size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi3),], aes(color='poi3'), size=3) +
scale_color_manual(values=list('poi1'='red','poi2'='blue','poi3'='green'))
Without manual color assignment. ggplot just uses the theme's default color palette.
p +
geom_point(data=dat1[which(dat1$idx %in% poi1),], aes(color='poi1'), size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi2),], aes(color='poi2'), size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi3),], aes(color='poi3'), size=3)
Adding a vertical line and showing that in the legend
Related to the follow up question in the comment to this solution: How would you add a vertical line for xintercept=poi3 and have that shown in the legend?
You could just add individual calls to geom_vline with separate values for xintercept=, but if you have many this is just kind of bad practice. A better practice is to have one geom_vline call where you set the data= as poi3. ggplot wants to receive a dataframe as data=, so in the code below you'll see I force this conversion via as.data.frame(.... Forcing a data frame makes a datframe of 2 observations with one column called "poi3", so that's what we will assign as the xintercept= aesthetic. This works... but you'll see it's not quite right:
p +
geom_point(data=dat1[which(dat1$idx %in% poi1),], aes(color='poi1'), size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi2),], aes(color='poi2'), size=3) +
geom_vline(data=as.data.frame(poi3), aes(xintercept=poi3, color='poi3'),
linetype=2, size=1) +
scale_color_manual(values=list('poi1'='red','poi2'='blue','poi3'='green2'))
The green line is added to the legend, but it's added "behind" all the points as a line + point. What we want is a separate legend. ggplot2 tries to combine legends where possible. What we'll do is kind of a cheat, which is to force ggplot2 to create another legend for linetype, and just set color='green2' outside of aes() in the geom_vline call. This removes the color of the line from the legend created for "colour" and adds another legend for "linetype" showing only our line. The final fix is to set the value for linetype via scale_manual_linetype. Since there's only one key here, you only need one value.
p +
geom_point(data=dat1[which(dat1$idx %in% poi1),], aes(color='poi1'), size=3) +
geom_point(data=dat1[which(dat1$idx %in% poi2),], aes(color='poi2'), size=3) +
geom_vline(
data=as.data.frame(poi3), aes(xintercept=poi3, linetype='poi3'),
color='green2', size=1) +
scale_color_manual(values=list('poi1'='red','poi2'='blue')) +
scale_linetype_manual(values=2)

mix discrete and continuous values to get a fill guide in ggplot2

I want to add a legend for filled rectangles in the background but I already used fill aesthetics for filling the bars of my bar plot.
How can I get the legend or create a matching legend by hand?
df <- data.frame(a=factor(c('a','b','c','c','d','e'), levels=c('a','b','c','d','e')),
x=seq(1,6),
b=factor(c('A','A','A','B','B','B'), levels=c('A','B')),
c=c(1,2,3,4,5,6),
d=rnorm(6))
ggplot(df, aes(x, c, fill=d, group=b)) +
geom_rect(aes(xmin=0.5,xmax=3.5,ymin=-Inf,ymax=Inf),alpha=0.05,fill="#E41A1C") +
geom_rect(aes(xmin=3.5,xmax=6.5,ymin=-Inf,ymax=Inf),alpha=0.05,fill="#377EB8") +
geom_bar(stat='identity', position=position_dodge()) +
coord_flip() +
scale_x_continuous(breaks=df$x, labels=df$a)
So I need a legend describing my two geom_rect areas. I was not able to map my two areas in any way to get a legend. In general the column df$b is describing the areas I do now by hand.
You can set colour= to variable b inside the aes() of both geom_rect(). This will make lines around the rectangles and also make legend. Lines can be removed setting size=0 for geom_rect(). Now using guides() and override.aes= you can change fill= for legend key.
ggplot(df, aes(x, c, fill=d, group=b)) +
geom_rect(aes(xmin=0.5,xmax=3.5,ymin=-Inf,ymax=Inf,colour=b),alpha=0.05,fill="#E41A1C",size=0) +
geom_rect(aes(xmin=3.5,xmax=6.5,ymin=-Inf,ymax=Inf,colour=b),alpha=0.05,fill="#377EB8",size=0) +
geom_bar(stat='identity', position=position_dodge()) +
coord_flip() +
scale_x_continuous(breaks=df$x, labels=df$a)+
guides(colour=guide_legend(override.aes=list(fill=c("#E41A1C","#377EB8"),alpha=0.3)))

How to change style settings in stacked barchart overlaid with density line (ggplot2)

I am trying to change the style settings of this kind of chart and hope you can help me.
R code:
set_theme(theme_bw)
cglac$pred2<-as.factor(cglac$pred)
ggplot(cglac, aes(x=depth, colour=pred2))
+ geom_bar(aes(y=..density..),binwidth=3, alpha=.5, position="stack")
+ geom_density(alpha=.2)
+ xlab("Depth (m)")
+ ylab("Counts & Density")
+ coord_flip()
+ scale_x_reverse()
+ theme_bw()
which produces this graph:
Here some points:
What I want is to have the density line as black and white lines separated by symbols rather than colour (dashed line, dotted line etc).
The other thing is the histogram itself. How do I get rid of the grey background in the bars?
Can I change the bars also to black and white symbol lines (shaded etc)? So that they would match the density lines?
Last but not least I want to add a second x or in this case y axis, because of flip_coord(). The one I see right now is for the density. The other one I need would then be the count data from the pred2 variable.
Thanks for helping.
Best,
Moritz
Have different line types: inside aes(), put linetype = pred2. To make the line color black, inside geom_density, add an argument color = "black".
The "background" of the bars is called "fill". Inside geom_bar, you can set fill = NA for no fill. A more common approach is to fill in the bars with the colors, inside aes() specify fill = pred2. You might consider faceting by your variable, + facet_wrap(~ pred2, nrow = 1) might look very nice.
Shaded bars in ggplot? No, you can't do that easily. See the answers to this question for other options and hacks.
Second y-axis, similar to the shaded symbol lines, the ggplot creator thinks a second y-axis is a terrible design choice, so you can't do it at all easily. Here's a related question, including Hadley's point of view:
I believe plots with separate y scales (not y-scales that are transformations of each other) are fundamentally flawed.
It's definitely worth considering his point of view, and asking yourself if those design choices are really what you want.
Different linetypes for densities
Here's my built-in data version of what you're trying to do:
ggplot(mtcars, aes(x = hp,
linetype = cyl,
group = cyl,
color = cyl)) +
geom_histogram(aes(y=..density.., fill = cyl),
alpha=.5, position="stack") +
geom_density(color = "black") +
coord_flip() +
theme_bw()
And what I think you should do instead. This version uses facets instead of stacking/colors/linetypes. You seem to be aiming for black and white, which isn't a problem at all in this version.
ggplot(mtcars, aes(x = hp,
group = cyl)) +
geom_histogram(aes(y=..density..),
alpha=.5) +
geom_density() +
facet_wrap(~ cyl, nrow = 1) +
coord_flip() +
theme_bw()

Changing the color in the legend with ggplot2 in R

I'm having two different problems with specifying the colors in my legends in ggplot. I've tried to make a simplified examples that shows my problem:
df <- data.frame(x=rep(1:9, 10), y=as.vector(t(aaply(1:10, 1, .fun=function(x){x:(x+8)}))), method=factor(rep(1:9, each=10)), DE=factor(rep(1:9, each=10)))
ggplot(df, aes(x, y, color=method, group=DE, linetype=DE)) + geom_smooth(stat="identity")
For some reason, the line types shown in the legend under the title DE are all blue. I'd like them to be black, but I have no idea why they're blue in the first place, so I'm not sure how to change them.
For my other problem, I'm trying to use both point color and point shape to show two different distinctions in my data. I'd like to have legends for both of these. Here's what I have:
classifiers <- c("KNN", "RF", "NB", "LR", "Tree")
des <- c("Uniform", "Gaussian", "KDE")
withoutDE <- c(.735, .710, .706, .628, .614, .720, .713, .532, .523, .557, .677, .641, .398, .507, .538)
withDE <- c(.769, .762, .758, .702, .707, .752, .745, .655, .721, .733, .775, .772, .749, .756, .759)
df <- data.frame(WithoutDE=withoutDE, WithDE=withDE, DE=rep(des, each=5), Classifier=rep(classifiers, 3))
df <- cbind(df, Method=paste(df$DE, df$Classifier, sep=""))
ggplot() + geom_point(data=df, aes(x=WithoutDE, y=WithDE, shape=Classifier, fill=DE), size=3) + ylim(0,1) + xlim(0,1) + xlab("AUC without DE") + ylab("AUC with DE") + scale_shape_manual(values=21:25) + scale_fill_manual(values=c("pink", "blue", "white"), labels=c("Uniform", "KDE", "Gaussian")) + theme(legend.position=c(.85,.3))
If I change the color to change as well as the fill (by putting color=DE into the aes), then those are visible in the legend. I like having the black border around the points, though. I'd just like to have the inside of the points in the legend reflect the point fill in the plot. (I'd also like to position the two legends side-by-side, but I really just want to get the color to work right now)
I've spent way too long googling about both of these problems and trying various solutions without any success. Does anyone have any idea what I'm doing wrong?
For question 1:
Give the legend for line type and the legend for colour the same name.
ggplot(df, aes(x, y, color=method, group=DE, linetype=DE)) +
geom_smooth(stat="identity") +
scale_color_discrete("Line") +
scale_linetype_discrete("Line")
For question 2:
I do not think your fills are matching your data. You should assign the name of the value to each colour in the scale_x_manual calls.
I couldn't get the black border for the points. Here is what I was able to get, though:
ggplot() +
geom_point(data=df, aes(x=WithoutDE, y=WithDE, shape=Classifier,
fill=DE, colour=DE), size=3) +
ylim(0,1) + xlim(0,1) +
xlab("AUC without DE") +
ylab("AUC with DE") +
scale_shape_manual(values=21:25) +
scale_fill_manual(values=c("Uniform"="pink", "KDE"="blue", "Gaussian"="white"),
guide="none") +
scale_colour_manual(values=c("Uniform"="pink", "KDE"="blue", "Gaussian"="white"),
labels=c("Uniform", "KDE", "Gaussian")) +
theme(legend.position=c(.85,.3))
I don't know if you can control the point type inside the legends. Maybe someone else with more knowledge of ggplot2 can figure it out.

Plot thick line with dark dots at data points in ggplot2

I want to plot a path and show where the datapoints are.
Combine Points with lines with ggplot2
uses geom_point() + geom_line() but I do not like that the dots are much thicker and the lines have a discontinuous look - x - x ----- x --- thus I decidet to
create my own dotted line:
mya <- data.frame(a=1:20)
ggplot() +
geom_path(data=mya, aes(x=a, y=a, colour=2, size=1)) +
geom_point(data=mya, aes(x=a, y=a, colour=1, size=1)) +
theme_bw() +
theme(text=element_text(size=11))
I like that the dots and the line have the same size. I did not use the alpha channel because I fear trouble with the alpha channel when I include the files in other programs.
open problems:
R should not create those legends
can R calculate the "darker colour" itself? darker(FF0000) = AA0000
how can I manipulate the linethickness? The size= parameter did not work as expected in R 2.15
Aesthetics can be set or mapped within a ggplot call.
An aesthetic defined within aes(...) is mapped from the data, and a legend created.
An aesthetic may also be set to a single value, by defining it outside aes().
In your case it appears you want to set the size to a single value. You can also use scale_..._manual(values = ..., guide = 'none') to suppress the creation of a legend.
This appears to be what you want with colour.
You can then use named colours such as lightblue and darkblue (see ?colors for more details)
ggplot() +
geom_line(data=mya, aes(x=a, y=a, colour='light'), size = 2) +
geom_point(data=mya, aes(x=a, y=a, colour='dark'), size = 2) +
scale_colour_manual(values = setNames(c('darkblue','lightblue'),
c('dark','light')), guide = 'none') +
theme_bw()

Resources