Lost colors and legend after ggplot upgrade - r

I really like the way ggplot2 2.0 improved the looks, but suspect that the upgrade changed the way colors and legend is defined. How can I update my code for ggplot 2.0?
The first abline should be black (and still is). Should not be in legend.
The ablines "Line1", "Line2", and "Line3" should have different colors, and be in legend. They are all black now.
The legend should be visible, but is not anymore.
library(ggplot2)
plot.data <- data.frame(x=c(2, 8), y=c(3, 6))
p <- ggplot(plot.data, aes(x=x, y=y))
p <- p + geom_point(color="black")
p <- p + geom_abline(intercept=0, slope=0.5, color="black", linetype="dashed")
#p <- p + geom_abline(intercept=0, slope=1, aes(color="Line1"), linetype="dashed", show_guide=TRUE)
p <- p + geom_abline(intercept=0, slope=1, aes(color="Line1"), linetype="dashed", show.legend=TRUE)
p <- p + geom_abline(intercept=0, slope=2, aes(color="Line2"), linetype="dashed")
p <- p + geom_abline(intercept=0, slope=3, aes(color="Line3"), linetype="dashed")
p <- p + xlim(0,10)
p <- p + ylim(0,10)
p <- p + theme(legend.title=element_blank(), legend.position="bottom")
p
With the original code (with # in example above) I get a warning message "show_guide has been deprecated. Please use show.legend instead`", but changing show_guide to show.legend above makes no difference.
Note: I'm not 100% sure it is the upgrade that is the problem, it might be my original example that is wrong.

I just repost my comment here as an answer.
to make the legend reappear, the intercept and the slope also have to be in the aes() call.
p + geom_abline(aes(intercept=0, slope=1, color="Line1"), linetype="dashed", show.legend=TRUE)

Related

How to show the part of the errorbar lines which are within the plot margins using `ggplot2`?

I have a grid of plots, all with the same y and x-axis scale. The plots represent time in the x-axe and mean values in the y-axe with their standard errors. My problem is that some errorbars are not entirely within the plot margins, and I wonder if there is some way to represent the part of the errorlines that are within the plot margins. Below I give a fake example and code to play with:
df <- data.frame(time=seq(-15,15,1),
mean=c(0.49,0.5,0.53,0.55,0.57,0.59,0.61,0.63,0.65,0.67,0.69,0.71,0.73,0.75,0.77,0.79,0.77,0.75,0.73,0.71,0.69,0.67,0.65,0.63,0.61,0.59,0.57,0.55,0.53,0.51,0.49),
sd=c(0.09,0.087,0.082,0.08,0.023,0.011,0.010,0.009,0.008,0.007,0.006,0.005,0.004,0.003,0.002,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.010,0.011,0.023,0.08,0.084,0.087,0.09))
Plot <- ggplot(df, aes(x=time, y=mean)) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), width=.3) +
geom_point(size=1) +
geom_line () +
theme_bw() +
scale_y_continuous(limits = c(0.49, 0.85), breaks = c(0.5, 0.65,0.8))
Plot
You need to set coord_cartesian limits rather than scale_y_continuous limits:
ggplot(df, aes(x=time, y=mean)) +
geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), width=.3) +
geom_point(size=1) +
geom_line () +
theme_bw() +
scale_y_continuous(breaks = c(0.5, 0.65,0.8)) +
coord_cartesian(ylim = c(0.49, 0.85))

Remove gaps in a stat_density2d ggplot chart without modifying XY limits

When I run this code:
ggplot() +
stat_density2d(data = Unit_J, aes(x=X, y=Y, fill=..level.., alpha=0.9), lwd= 0.05, bins=50, col="blue", geom="polygon") +
scale_fill_continuous(low="blue",high="darkblue") +
scale_alpha(range=c(0, 0.03), guide="none") +
xlim(-6600,-3800) + ylim(400,2500) +
coord_fixed(expand=FALSE) +
geom_point(data = Unit_J, aes(x=X, y=Y), alpha=0.5, cex=0.4, col="darkblue") +
theme_bw() +
theme(legend.position="none")
I get this plot:
I know that increasing in this case X lims would solve the problem of unclosed lines shown on the left and right.
However, I want to keep these limits unchanged so that those "bugs" don't appear, and simply they must be beyond the limits, somehow hidden without creating those horrible lines.
Is there any possibility?
EDIT (download data here):
In order to ease and reproduce the example, you can download the data here
The trick is to expand the canvas using xlim and ylim so that there is enough room for ggplot to draw complete contours around the data. Then you can use tighter xlim and ylim parameters within the coord_fixed term to show the window you want...
ggplot() +
stat_density2d(data = Unit_J, aes(x=X, y=Y, fill=..level.., alpha=0.9),
lwd= 0.05, bins=50, col="blue", geom="polygon") +
scale_fill_continuous(low="blue",high="darkblue") +
scale_alpha(range=c(0, 0.03), guide="none") +
xlim(-7000,-3500) + ylim(400,2500) + #expanded in x direction
coord_fixed(expand=FALSE,xlim=c(-6600,-3800),ylim=c(400,2500)) + #added parameters
geom_point(data = Unit_J, aes(x=X, y=Y), alpha=0.5, cex=0.4, col="darkblue") +
theme_bw() +
theme(legend.position="none")

Use position_jitterdodge to plot points, and add highlighted points that are also dodged

I have some data where x is categorical, y is numeric, and color.var is another categorical variable that I would like to color by. My goal is to plot all of the points using position_jitterdodge(), and then highlight a couple of the points, draw a line between them, and add labels, while making sure these highlighted points line up with the corresponding strips of points that were plotted using position_jitterdodge(). The highlighted points are aligned properly when all factors are present in the variable used to dodge, but it does not work well when some factors are missing.
Minimal (non-)working example
library(ggplot2)
Generate some data
d = data.frame(x = c(rep('x1', 1000), rep('x2', 1000)),
y = runif(n=2000, min=0, max=1),
color.var= rep(c('color1', 'color2'), 1000),
facet.var = rep(c('facet1', 'facet1', 'facet2', 'facet2'), 500))
head(d)
dd = d[c(1,2,3,4,1997,1998, 1999,2000),]
dd
df1 = dd[dd$color.var=='color1',] ## data for first set of points, labels, and the line connecting them
df2 = dd[dd$color.var=='color2',] ## data for second set of points, labels, and the line connecting them
df1
dw = .75 ## Define the dodge.width
Plot all points
Here are all of the points, separated using position_jitterdodge() and the aesthetic fill.
ggplot() +
geom_point(data=d, aes(x=x, y=y, fill=color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
theme(axis.title = element_blank()) +
theme(legend.position="top")
That works well.
Additional highlighted points.
Here is the same plot, with additional points in dd added.
ggplot() +
geom_point(data=d, aes(x=x, y=y, fill =color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
geom_point(data=dd, aes(x=x, y=y, color=color.var ), position=position_dodge(width=.75), size=4 ) +
geom_line(data=dd, aes(x=x, y=y, color=color.var, group=color.var ), position=position_dodge(width=.75), size=1 ) +
geom_label(data=dd, aes(x=x, y=y, color=color.var, group=color.var, label=round(y,1)), position=position_dodge(width=.75), vjust=-.5) +
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
scale_color_manual(values=c( 'blue', 'gray40')) +
theme(axis.title = element_blank())+
theme(legend.position="top")
This is what I want it to look like. However, this only works properly if both factors of the color.var variable are in the set of points to highlight.
If both factors aren't present in the new data, the horizonal alignment fails.
Highlight points, only one factor present
Here is an example where only the 'color1' factor (blue) is present. Note that data=dd was replaced with data=df1 (data that only contains blue highlighted dots) in this code.
ggplot() +
geom_point(data=d, aes(x=x, y=y, fill =color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
geom_point(data=df1, aes(x=x, y=y, color=color.var ), position=position_dodge(width=.75), size=4 ) +
geom_line(data=df1, aes(x=x, y=y, color=color.var, group=color.var ), position=position_dodge(width=.75), size=1 ) +
geom_label(data=df1, aes(x=x, y=y, color=color.var, group=color.var, label=round(y,1)), position=position_dodge(width=.75), vjust=-.5) +
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
scale_color_manual(values=c( 'blue', 'gray40')) +
theme(axis.title = element_blank())+
theme(legend.position="top") +
scale_x_discrete(drop=F)
The highlight blue dots appear between the blue and gray dots, instead of aligned with the blue dots. Note that the additional code scale_x_discrete(drop=F) had no apparent effect on the alignment.
A manual solution
One possible fix is to edit the x coordinate manually, like this
ggplot(data=d, aes(x=x, y=y)) +
geom_point(aes(fill=color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray') +
geom_point(data=df1, aes(x=as.numeric(x)-dw/4, y=y), alpha=.9, size=4 , color='blue') + ## first set of points
geom_line( data=df1, aes(x=as.numeric(x)-dw/4, y=y , group=color.var ), color='blue', size=1) + ## first line
geom_label(data=df1, aes(x=as.numeric(x)-dw/4, y=y , label=round(y,1)), color='blue', vjust=-.25)+ ## first set of labels
facet_wrap(~facet.var) +
scale_fill_manual(values=c( 'lightblue','gray'))+
theme(axis.title = element_blank() +
theme(legend.position="top")
An adjustment of 1/4 of the dodge.width seems to work. This works fine, but it seems like there should be a better way, especially since I will eventually want to do this with 4-5 sets of highlighted points/lines, which may all be all be the same color.var, like the blue 'color1' factor above. Repeating this 4-5 times would be cumbersome. I will also eventually want to do this will 5-10 different figures. I suppose dodge.width*1/4 will always work, and copying and pasting might do the trick, but would like to know if there is a better way.
Here is a solution based on #aosmith's comment. Basically, just need to add this code before using ggplot:
library(dplyr) ## needed for group_by()
library(tidyr) ## needed for complete()
df1 = df1 %>% group_by(facet.var, x) %>% complete(color.var)
That adds extra rows to the data so that all the levels of color.var are present. Then the code given in the question, along with a couple of small edits that fix the legend, can be used:
ggplot() +
geom_point(data=d , aes(x=x, y=y, fill =color.var), position=position_jitterdodge(dodge.width=dw), size=3, alpha=1, shape=21, color='darkgray', show.legend=T) +
geom_point(data=df1, aes(x=x, y=y, color=color.var ), position=position_dodge(width=.75), size=4, show.legend=T ) +
geom_line( data=df1, aes(x=x, y=y, color=color.var, group=color.var ), position=position_dodge(width=.75), size=1, show.legend=F ) +
geom_label(data=df1, aes(x=x, y=y, color=color.var, group=color.var, label=round(y,1)), position=position_dodge(width=.75), vjust=-.5, show.legend=F) +
facet_wrap(~facet.var) +
scale_fill_manual( values=c( 'lightblue','gray'), name='Background dots', guide=guide_legend(override.aes = list(color=c('lightblue', 'gray')))) +
scale_color_manual(values=c( 'blue', 'gray40') , name='Highlighted dots') +
theme(axis.title = element_blank())+
theme(legend.position="top")+
scale_x_discrete(drop=F)

ggplot2: legends for different aesthetics

I first plot histogram for a group of simulated data and fill the bars with one colour. Then I add the line of the density function from which the data was simulated from and make the line with a different colour. Now I want use legends to show one colour (the fill colour of the histogram) is for samples whereas the other (the colour of the line) is for theoretical density. How can I achieve this?
The code is as follows
require(ggplot2)
df <- data.frame(x=rnorm(10^4))
p <- ggplot(df, aes(x=x)) + geom_histogram(aes(y=..density..), fill='steelblue', colour='black', alpha=0.8, width=0.2)
x <- seq(-4, 4, 0.01)
df <- data.frame(x=x, y=dnorm(x))
p <- p + geom_line(data=df, aes(x=x, y=y), colour='red', size=1.5)
p
You can do this by adding a new column to each of your data frames to create fill and colour aesthetics to go into the legend. In each case, there's only one category, but putting them inside the aes() gives you the legends you want:
require(ggplot2)
df <- data.frame(x=rnorm(10^4), fill=rep("Sample", 10^4))
p <- ggplot(df, aes(x=x)) + geom_histogram(aes(y=..density.., fill=fill),
colour='black', alpha=0.8, width=0.2) +
scale_fill_manual(values="steelblue") + labs(fill="")
x <- seq(-4, 4, 0.01)
df <- data.frame(x=x, y=dnorm(x), colour=rep("Theoretical Density",length(x)))
p <- p + geom_line(data=df, aes(x=x, y=y, colour=line), size=1.5) +
scale_colour_manual(values="red") + labs(colour="")
Without changing your data at all, you can specify literal aes() values that you can define later via manual scales.
df <- data.frame(x=rnorm(10^4))
p <- ggplot(df, aes(x=x)) + geom_histogram(aes(y=..density.., fill="samples"),
alpha=0.8, colour="black", width=0.2)
p <- p+scale_fill_manual("",breaks="samples", values="steelblue")
x <- seq(-4, 4, 0.01)
df <- data.frame(x=x, y=dnorm(x))
p <- p + geom_line(data=df, aes(x=x, y=y, colour="theory"), size=1.5)
p <- p+scale_color_manual("",breaks="theory", values="red")

geom_smooth in ggplot causes part of plot background to change colour

How can I avoid the grey shading of the plot area that occurs when plotting the following data?
df <-data.frame(x = c(0,0.2,0.5), y = c(0.6,0.7,0.9))
p <-ggplot(df, aes(x, y, ymin=0, ymax=1, xmin=0, xmax=1))
p <- p + geom_point(alpha=2/10, shape=21,
fill="blue", colour="black", size=5)
p
So fine up until this point but then adding a line equation using geom_smooth causes part of the background to become grey.
p <- p + geom_smooth(method="lm", se=FALSE, formula=y~x, colour="black")
p
Any suggestions on how to avoid this? Thanks.
Add fill=NA to your geom_smooth call:
p + geom_smooth(method="lm", se=FALSE, formula=y~x,colour="black",fill=NA)

Resources