I am trying to make a scatterplot in ggplot2 with a size mapping to a third variable and density2d contours. It seems as if the legend is being confused by the inclusion of density2d contours.
For example, the following code works:
library('ggplot2')
set.seed(1)
x=rnorm(100); y=rnorm(100,sd=10); z=seq(1,10,length.out=100)
dd=data.frame(x=x,y=y,z=z)
ggplot(dd,aes(x,y,size=z))+geom_point()
But now, note the legend behaves unusually when I add in a call to stat_density2d(). In particular, the plot legend shows blue blocks instead of black circles:
ggplot(dd,aes(x,y,size=z))+geom_point()+stat_density2d()
As size= is one of the aesthetics you can set for the stat_density2d() and in this case it is set in ggplot() call, legend is made for both - lines and points (points are hided under lines in legend as geom_point() is called before stat_density2d()). To remove blue lines from legend, you can set manually size=0.5 (or some other value) inside the stat_density2d() and then legend will be correct.
ggplot(dd,aes(x,y,size=z))+geom_point()+stat_density2d(size=0.5)
Related
Is there a reason why ggplot might mess with the geom_point shape in the legend?
In the actual plot everything looks with the shapes correctly plotted as circles, but in the legend it shows them as weird boxes / squares, i.e. it is showing this:
But it should show this:
Could it be because I have an ifelse in my geom_point ? This is what I have here for this part:
geom_point(aes( y=y, colour=ifelse( (ty>308)&(Time < chron(times=c('08:30:30.0'))), ifelse(side=='left', 'red', 'blue'),'gray')), na.rm = T)
This issue is actually because geom_point and geom_line are both plotted and the points are varying according to the size parameter. ggplot is trying to show a point on a line which looks good when it is small and clear but becomes strange and box-like as the size varies.
To make it clearer, turning off the legend for either the line or the points will keep just one.
For example:
geom_line(aes(y=foo , colour='green'), show.legend = F)
I'm finding the combined legend for shape and linetype to be difficult to decipher. specifically, the shape is hard to see because it is behind the line and it is too small.
library(ggplot2)
ggplot(mtcars)+
geom_point(aes(x=hp,y=mpg,shape=as.factor(cyl)))+
geom_smooth(aes(x=hp,y=mpg,linetype=as.factor(cyl)),method='lm')+
theme_bw(base_size=18)
How do I increase the size of the shapes in the legend without increasing the size of the line?
this attempt below increases the size for both (not what I want). the order of the guide_legend also does not seem to affect the order of the symbols in the legend keys. Changing the order of the geom_point and geom_smooth would give the desired result in the legend but not in the plot.
+guides(linetype=guide_legend('Cylinders'),shape=guide_legend('Cylinders',override.aes=list(size=3)))
I was also hoping theme(legend.key.size=grid::unit(2,'cm')) would scale up the size of the objects in the legend key but it doesn't appear to do so.
suggestions?
also open to other ideas how to make the graph more legible.
The legend produces the lines and points in the order that they are plotted, so in order to get the points in front of the line you could do this:
ggplot(mtcars)+
geom_smooth(aes(x=hp,y=mpg,linetype=as.factor(cyl)),method='lm')+
geom_point(aes(x=hp,y=mpg,shape=as.factor(cyl)))+
theme_bw(base_size=18)
Changing the size of the point in the legend is a little more frustrating. Maybe you want to try a hack that allows you to take a legend off of one plot and put it on another:
library(gtable)
library(gridExtra)
# Has the legend you want
p1 <- ggplot(mtcars)+
geom_smooth(aes(x=hp,y=mpg,linetype=as.factor(cyl)),method='lm')+
geom_point(aes(x=hp,y=mpg,shape=as.factor(cyl)),size=3)+
theme_bw(base_size=18)+labs(shape="Cylinders",linetype="Cylinders")
# Has the plot you want
p2 <- ggplot(mtcars)+
geom_smooth(aes(x=hp,y=mpg,linetype=as.factor(cyl)),method='lm')+
geom_point(aes(x=hp,y=mpg,shape=as.factor(cyl)))+
theme_bw(base_size=18)+theme(legend.position="none")
# Take the legend from p1
fill.legend <- gtable_filter(ggplot_gtable(ggplot_build(p1)), "guide-box")
legGrob <- grobTree(fill.legend)
# Put the legend from p1 onto p2
grid.arrange(p2, legGrob, ncol=2, widths = c(6,1))
I'm fairly new to ggplot2, and I'm trying to create a contour plot of data that has missing values. Because there's missing values I can't have the contours by themselves, so I'm combining a tiles background with a contour. The problem is the labels are the same colour as the background.
Suppose I have data like so:
DF1 <- data.frame(x=rep(1:3,3),y=rep(1:3,each=3),z=c(1,2,3,2,3,4,3,NA,NA))
I can make a plot like this:
require(ggplot2); require(directlabels)
plotDF <- ggplot(DF1,aes(x,y,z=z)) + geom_tile(aes(fill=z)) + stat_contour(aes(x,y,z=z,colour= ..level..),colour="white")
direct.label(plotDF)
This gives me a plot similar to what I want but I'd like to be able to change the colours of the labels to be black. Any ideas?
I spotted a similar post and thought this would be easy, something along the lines of direct.label(p, list("last.points", colour = "black"). I could not make it work, unfortunately; I believe, this is not directly supproted.
I then decided to use black magic and managed to do the trick by manually overriding the colour scale:
direct.label(plotDF +
scale_colour_gradient(low="black", high="black"))
I'm relatively new to ggplot2, and I'm having trouble adding appropriate labels to my contours. I would love to be able to add the labels without the directlabels package, but I haven't found a way to, so if you know of a way to customize labels without directlabels, I would love to here it.
Using the classic volcano example, I can add labels to the default contour plot using the directlabels packet in the following way:
library(plyr)
library(ggplot2)
library(directlabels)
library(reshape)
volcano<-melt(volcano)
v<-ggplot(volcano, aes(x,y,z=z))
e<-v + stat_contour(aes(colour=..level..))
direct.label(e)
In the above example, the labels are added appropriately, but things become more complicated if I try to specify my own break points for the contours:
e<-v + stat_contour(aes(breaks=c(160, 170, 180), colour=..level..))
direct.label(e)
Now, the contours are specified by the breaks I have provided, but labels still appear for all of the default contours. How do I only plot only labels for the graphed contours?
A related issue, how would I plot labels for contour levels not included in the default? Say a break of 165:
e<-v + stat_contour(aes(breaks=c(165), colour=..level..))
direct.label(e)
Thanks for any help!
The current development version (directlabels_2013.6.15 with ggplot2_0.9.3.1) should fix your problem (as the author of the directlabels package explained to me). You can install it with:
install.packages("directlabels", repos="http://r-forge.r-project.org")
And then:
library(plyr)
library(ggplot2)
library(directlabels)
library(reshape)
volcano<-melt(volcano)
v<-ggplot(volcano, aes(X1,X2,z=value))
e<-v + stat_contour(aes(colour=..level..), breaks=c(165))
direct.label(e)
I noted several other limitations with simple workarounds:
the first ggplot call must contain the z aesthetic
this works only with the stat_contour (and not with the geom_contour)
the colour aesthetic must be defined in the stat_contour call and set to ..level..
Finally, if you want to control the label and contour line colours (black labels and blue contour lines for instance), you can achieved this as follow:
e<-v + stat_contour(aes(colour=..level..), colour = "blue", breaks=c(165))
e<-e + scale_colour_continuous(low = "#FF0000", high = "#FF0000")
direct.label(e)
The following code assigns a manual color scale of red and black to my points:
require(ggplot2)
require(directlabels)
dtest <- data.frame(x=1:20,
y=rnorm(20,0,5),
v=seq(1,2))
p <- ggplot(dtest, aes(x=x,y=y,color=as.factor(v))) + geom_point() + scale_colour_manual(values=c("red","black"))
p #this looks good; red and black as intended
direct.label(p) #this falls back on the default colors
But when I apply direct.label() to the same plot, it overrides the color scale in favor of the ggplot default. Is there a way to prevent this? If not, what's the best way to assign new colors to the default ggplot scale?
Thanks,
Matt
This happens because direct.label(p) operates by adding the label geom to p, then by hiding the color legend, since labeling the colors twice would be redundant. One way to hide the color legend is by adding scale_colour_discrete(legend=FALSE), and this is what I do inside of direct.label. So when directlabels applies scale_colour_discrete, your scale_colour_manual will be lost. The workaround is to use the following idiom:
p <- ggplot(...)
direct.label(p)+
scale_colour_manual(...)