I know I'm not the first to ask a question in this arena but I haven't been able to figure out the solution to my particular quandary. Here's a stripped-down example of my problem.
data<-data.frame(Est=c(1:20,1:20),Measured=c(1:5,5:9,1:6,3:6,1:6,3:6,1:4,4,4:8),variable=c(rep("Plot1",20),rep("Plot2",20)))
p<-ggplot(data,aes(y=Est,x=Measured,shape=variable))
p<- p + geom_point(stat="identity") +coord_fixed(xlim=c(0,25),ylim=c(0,25)) + theme_bw()
p #If you plot the figure at this point, the points stand alone in the legend
p<-p+ geom_abline(intercept=0,slope=1,aes(linetype="1:1",color="1:1"),show_guide=TRUE)
p # Once the geom_abline is added, there are lines through the points. :(
p<-p+scale_color_manual(name="Lines",
values=c("1:1"="black"))
p<- p + scale_linetype_manual(name="Lines",
values=c("1:1"=2))
p<-p + scale_shape_manual(values=c(0,20), name = "")
p<- p+xlab(expression(paste("Measured volume(",ducks^{3},"",ha^{-1},")",sep="")))
p<-p+ ylab(expression(paste("Estimated volume (",ducks^{3},"",ha^{-1},")",sep="")))
As you can see, the legend for the points includes slashes (which I think are actually a line), and I would really prefer that the points were alone.
While the example code has only 1 line and linetype, the actual figure I've made includes five different lines of varying colors and linetypes, and thus I need a solution that allows me to include multiple geom_abline calls with color and linetype specified.
And no, I'm not really measuring the volume of anything in ducks, although that would be really entertaining to study...
Override the aesthetic mapping:
p + guides(shape = guide_legend(override.aes = list(linetype = 0)))
I always end up trying to override aesthetics by setting them to NULL, but for some reason that intuition is usually wrong.
Related
I'm having problems renaming my figure legend. When I try using scale_color_discrete to do this the legend duplicates on the graph:
This is the code I've used:
Scoping <- read.csv("Data/scoping.csv")
#Enzyme column must be turned into a factor
Scoping$Enzyme <- as.factor(Scoping$Enzyme)
#Creating scatterplot called scopplt
scopplt <- ggplot(Scoping,aes(x=Time,y=PNP,shape=Enzyme, color=Enzyme))+
geom_point(size=2)+
theme_classic()+
scale_y_continuous(limits=c(0,120), breaks = c(0,30,60,90,120), name = "[PNP] µM")+
scale_x_continuous(limits=c(0,12), breaks = c(0,2,4,6,8,10,12), name = "Time (min)")+
theme(legend.position = c(0.2, 0.6))
scopplt
# Adding linear regression
scopplt+geom_smooth(method=lm,se=FALSE,fullrange=TRUE,
aes(color=Enzyme)) +
scale_color_discrete(name= "[Enzyme] µM")
Does anyone know why this is happening. Thanks.
From what I can tell, you are calling scale_color_discrete because you are trying to rename the legend. If that is indeed what you trying to do with that line, you are taking the wrong approach. The problem is that you are changing both the color and shape of the points by Enzyme, and scale_color_discrete only applies to the color. To change the legend title, you can do what teunbrand suggested so that ggplot knows that you want the same title for the color and shape, thereby putting the two legends together. Or you can also replace scale_color_discrete(name = "[Enzyme] µM") with labs(color = "[Enzyme] µM", shape = "[Enzyme] µM"). My intuition tells me there should be a simpler way of doing this, but I am unable to figure it out at this point in time.
I would like to use customized linetypes in ggplot. If that is impossible (which I believe to be true), then I am looking for a smart hack to plot arrowlike symbols above, or below, my line.
Some background:
I want to plot some water quality data and compare it to the standard (set by the European Water Framework Directive) in a red line. Here's some reproducible data and my plot:
df <- data.frame(datum <- seq.Date(as.Date("2014-01-01"),
as.Date("2014-12-31"),by = "week"),y=rnorm(53,mean=100,sd=40))
(plot1 <-
ggplot(df, aes(x=datum,y=y)) +
geom_line() +
geom_point() +
theme_classic()+
geom_hline(aes(yintercept=70),colour="red"))
However, in this plot it is completely unclear if the Standard is a maximum value (as it would be for example Chloride) or a minimum value (as it would be for Oxygen). So I would like to make this clear by adding small pointers/arrows Up or Down. The best way would be to customize the linetype so that it consists of these arrows, but I couldn't find a way.
Q1: Is this at all possible, defining custom linetypes?
All I could think of was adding extra points below the line:
extrapoints <- data.frame(datum2 <- seq.Date(as.Date("2014-01-01"),
as.Date("2014-12-31"),by = "week"),y2=68)
plot1 + geom_point(data=extrapoints, aes(x=datum2,y=y2),
shape=">",size=5,colour="red",rotate=90)
However, I can't seem to rotate these symbols pointing downward. Furthermore, this requires calculating the right spacing of X and distance to the line (Y) every time, which is rather inconvenient.
Q2: Is there any way to achieve this, preferably as automated as possible?
I'm not sure what is requested, but it sounds as though you want arrows at point up or down based on where the y-value is greater or less than some expected value. If that's the case, then this satisfies using geom_segment:
require(grid) # as noted by ?geom_segment
(plot1 <-
ggplot(df, aes(x=datum,y=y)) + geom_line()+
geom_segment(data = data.frame( df$datum, y= 70, up=df$y >70),
aes(xend = datum , yend =70 + c(-1,1)[1+up]*5), #select up/down based on 'up'
arrow = arrow(length = unit(0.1,"cm"))
) + # adjust units to modify size or arrow-heads
geom_point() +
theme_classic()+
geom_hline(aes(yintercept=70),colour="red"))
If I'm wrong about what was desired and you only wanted a bunch of down arrows, then just take out the stuff about creating and using "up" and use a minus-sign.
Working with RStudio 0.98.1103, I am creating two versions of exactly the same graph: One with colors and one without. Since both graphs are exactly the same (apart from the coloring) I want to avoid typing nearly the same commands again. Hence, I create the colored plot, save it, manipulate it to make it black-grey-white and save the reduced version:
library(ggplot2)
bp <- ggplot(data=PlantGrowth, aes(x=group, y=weight)) +
geom_line(aes(color=group)) + theme(legend.position="none")
bp_bw <- bp + theme_bw() +
geom_line() + theme(legend.position="none")
ggsave("bp_bw.png", bp_bw)
Although bp looks quite normal, bp_bw doesn't. There is still a blury color shining behind the black bars (red - green - blue):
Closeup:
How can I get rid of this colors, i.e. remove all color completely from bp? Only restriction: I have to create the colored graphs first (although of course a different order would work).
I think a better solution is to create a base and only add the coloring part when needed:
bp <- ggplot(data=PlantGrowth, aes(x=group, y=weight)) +
theme_bw() + theme(legend.position="none")
bp_col <- bp + geom_line(aes(color=group))
bp_bw <- bp + geom_line()
This (more-or-less) makes sense. Your bp_bw code doesn't get rid of the old colored lines, it just adds black lines on top. Anti-aliasing as the image is displayed/saved lets some of the color through on the edges.
My recommendation is to modify the color scale rather than overplot black on top:
bp_bw2 = bp + scale_color_manual(values = rep("black", 20)) + theme_bw()
This will change the colors to all black rather than plotting black on top of colors. The rep("black", 20) is kind of a hack. Apparently values aren't recycled by scale_color_manual, but extra values aren't used so you need to give it a vector at least as long as the number of colors.
This also has the advantage of not needing to repeat the geom call, and if you had previously defined a color scale this will overwrite it. If you want to be more general you could also add a scale_fill_manual(), and you probably want to specify guide = FALSE so that you don't get a very unhelpful legend.
You also might want to check out scale_colour_grey, just because it's B&W doesn't mean all the colors have to be the same.
I have a scatterplot that breaks the points out into different colors by the category. I want one of these categories to have a line connecting the dots to highlight this category's data. I'm having trouble figuring this out...
Round <- read.csv("http://goo.gl/3c3vBU") # Data
qplot(factor(Round), Opp.Landed, data=floyd, color=Opponent, size=Opp.Percent.Landed, alpha = I(0.7)) +
labs(x="Round", y="Punches Landed", title="Opponent Punches Landed / Percentage", colour="Boxer", size="Connect Percentage") +
scale_linetype_manual(values=1:2, labels=c("Boxer", "Connect Percentage")) +
guides(colour = guide_legend(override.aes = list(size=5)))
The ftheme code is just colors and formatting. Any ideas? I've tried adding geom_line(aes(linetype=floyd[Opponent="Manny Pacquiao"]), size=1) but it errors out with
Error in [.data.frame`(floyd, Opponent = "Manny Pacquiao") : unused argument (Opponent = "Manny Pacquiao")
EDIT: I've updated the code above to exclude ftheme so it's reproducable. Please see the sample dataset from with three categories. I just want any one of these to have connected points: http://goo.gl/3c3vBU
I can't give a tailored answer without being able to run your code on a sample of your data, but you can use scale_color_manual to set the colour of the category you want to highlight to, say, "red" and set all the others to NA. For example, if the category you want to highlight is the second category and you have a total of five categories, then add this to your plot code:
scale_colour_manual(values=c(NA, "red", rep(NA,3)))
If you have points that are tied to the color aesthetic as well, then you'll need to change the points to a fill aesthetic (e.g., fill=Opponent) and use a filled point marker that you can set manually using shape or pch. Otherwise, your point markers will disappear along with the lines. Marker numbers 21 through 25 are filled (see ?pch for more on point markers).
UPDATE: Here's my attempt using the data you provided. I'm not exactly sure how you want the legends and other details to look, so let me know if this works. I've switched to ggplot, as I don't know the ins and outs of qplot.
ggplot(floyd, aes(factor(Round), Opp.Landed, color=Opponent,
fill=Opponent, group=Opponent, size=Opp.Percent.Landed),
alpha = 0.7, pch=21) +
geom_point(pch=21, colour=NA) +
geom_line() +
labs(x="Round", y="Punches Landed", title="Opponent Punches Landed / Percentage",
colour="Boxer", size="Connect Percentage") +
scale_linetype_manual(values=1:2, labels=c("Boxer", "Connect Percentage")) +
scale_colour_manual(values=c(hcl(15,100,65), NA, NA), guide="none") +
guides(fill = guide_legend(override.aes = list(size=5)))
Try to add:
geom_line(data=subset(floyd,Opponent=="Manny Pacquiao"), aes(factor(Round), Opp.Landed, group=Opponent), size = 2)
Very easy piece of code which makes a subset of your data of which gives a nice line of size 2 through your data points.
(for the image I used the opponent Miguel Cotto since you did not provide Manny Pacquiao in the data set)
From what I can find on stackoverflow, (such as this answer to using two scale colour gradients on one ggplot) this may not (yet) be possible with ggplot2.
I want to create a bubbleplot with two size aesthetics, one always larger than the other. The idea is to show the proportion as well as the absolute values. Now I could colour the points by the proportion but I prefer multi-bubbles. In Excel this is relatively simple. (http://i.stack.imgur.com/v5LsF.png) Is there a way to replicate this in ggplot2 (or base)?
Here's an option. Mapping size in two geom_point layers should work. It's a bit of a pain getting the sizes right for bubblecharts in ggplot though.
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(size = disp), shape = 1) +
geom_point(aes(size = hp/(2*disp))) + scale_size_continuous(range = c(15,30))
To get it looking most like your exapmle, add theme_bw():
P <- p + theme_bw()
The scale_size_continuous() is where you have to just fiddle around till you're happy - at least in my experience. If someone has a better idea there I'd love to hear it.