I am trying to create a plot containing two lines with different shapes and colour.
I have checked a number of similar questions online but I have not been successful. I have been able to do the following so far
library(reshape2)
library(ggplot2)
library(latex2exp)
v1 <-c(0.000120,-0.000085,-0.000018,0.000005)
v2 <- c(0.000164,0.000041,-0.000032,0.000031)
v3 <- c(500,1000,5000,10000)
dfr <- data.frame(rate1=v1,rate2=v2,quantity=v3)
dfr <- melt(dfr,id='quantity',value.name="res")
ggplot(dfr, aes(x=quantity, y=res,group=variable,shape=variable)) +
geom_line(size=1, aes(linetype=variable,colour=variable)) +
geom_point( size=4,aes(colour=variable))+ coord_cartesian(ylim = c(-0.0001,0.0002)) +
scale_x_continuous(breaks=c(500,1000,5000,10000))+
scale_linetype_manual(values=c("solid", "longdash"))+
geom_hline(yintercept = 0,linetype="dotted",size=1)
However, I want to do the following:
Replace the legend texts/labels: rate1 and rate2 with two Greek lambda symbols.
Finally, hide the legend title variable.
When I try to include this: scale_colour_manual( values=c('#F8766D','#00BFC4'),labels = unname(TeX(c(" $\\lambda_1$", "$\\lambda_2$")))), so as to change the legend text, I get an extra legend below:
Please how can I fix this? Thanks!
The issue is that by changing the labels in scale_linetype but not for the other scales (color and shape) ggplot2 will no longer merge them into one legend. Hence you have the change the labels for the other scales as well. However, using Tex() I did not manage to make this work. But following this post using bquote worked fine. Finally, to get rid of the legend title simply use labs() to set the title for all three scales to NULL
EDIT Thanks to #mischva for checking and pointing out that using labels <- unname(TeX(c(" $\\lambda_1$", "$\\lambda_2$"))) will also work fine. Interestingly it does not work if one puts it directly into the three scales functions. That's what I tried.
library(reshape2)
library(ggplot2)
library(latex2exp)
v1 <-c(0.000120,-0.000085,-0.000018,0.000005)
v2 <- c(0.000164,0.000041,-0.000032,0.000031)
v3 <- c(500,1000,5000,10000)
dfr <- data.frame(rate1=v1,rate2=v2,quantity=v3)
dfr <- melt(dfr,id='quantity',value.name="res")
labels <- c(bquote(lambda[1]), bquote(lambda[2]))
ggplot(dfr, aes(x=quantity, y=res,group=variable,shape=variable)) +
geom_line(size=1, aes(linetype=variable,colour=variable)) +
geom_point( size=4,aes(colour=variable))+ coord_cartesian(ylim = c(-0.0001,0.0002)) +
scale_x_continuous(breaks=c(500,1000,5000,10000))+
scale_linetype_manual(values=c("solid", "longdash"), labels = labels)+
scale_shape_discrete(labels = labels)+
scale_colour_discrete(labels = labels) +
labs(color = NULL, linetype = NULL, shape = NULL) +
geom_hline(yintercept = 0,linetype="dotted",size=1)
Related
I've created a ggplot2 graph using the basic code below:
my_df %>%
ggplot(aes(conv_norm, vot_norm, color = language:poa)) +
geom_smooth(method = "glm", se=FALSE) +
theme(
...
)
[I've left out the formatting commands from the theme() layer]
And I got a graph that looks like this:
Now, my question is: how can I add extra space only in between two legend items? I've looked online and have found ways to increase the spacing between all items in the legend, but I only want extra spacing between the English items and the Spanish items. Is there a way to add a 1-in distance between these language groups?
Well, I don't know of an elegant, simple solution to do what you are asking to do... but by working with how legends are drawn and adjusting some of the elements, we can come up with a really "hacky" solution. ;)
Here's a sample dataset that kind of simulates what you shared, along with the plot:
set.seed(12345)
my_df <- data.frame(
lang = rep(c(paste('English',1:3), paste('Spanish',1:3)),2),
x = c(rep(0,6), rep(1,6)),
y = rnorm(12, 10,2))
library(ggplot2)
p <- ggplot(my_df, aes(x,y, color=lang)) + geom_line()
p
The approach here is going to be to combine all the following individual steps:
Add a "blank" legend entry. We do this by refactoring and specifying the levels of the column mydf$lang to include a blank entry in the correct position. This will be the final order of the items in the legend.
Use scale_color_manual() to set the colors of the legend items manually. I make sure to use "NA" for the blank entry.
Within scale_color_manual() I use the drop=FALSE setting. This includes all levels for a factor, even if there is no data on the plot to show. This makes our blank entry show on the legend.
Use the legend.background theme element to draw transparent boxes for the legend key items. This is so that you don't have a white or gray box for that blank entry.
Putting it all together you get this:
my_df$lang <- factor(my_df$lang, levels=c(paste('English',1:3), '', paste('Spanish',1:3)))
ggplot(my_df, aes(x,y, color=lang)) +
geom_line() +
scale_color_manual(
values=c(rainbow(6)[1:3], 'NA', rainbow(6)[4:6]),
drop=FALSE) +
theme( legend.key = element_rect(fill='NA') )
Alternatively, you could use guides(color=guide_legend(override.aes... to set the colors, but you need the drop=FALSE part within scale_color_manual() get the blank level to draw in the legend anyway.
Another option would be to create two separate legends. Either by using two different aesthetics, or you can use color twice, e.g with ggnewscale - thanks to user chemdork123 for the fake data +1.
library(tidyverse)
library(ggnewscale)
set.seed(12345)
my_df <- data.frame(
lang = rep(c(paste('English',1:3), paste('Spanish',1:3)),2),
x = c(rep(0,6), rep(1,6)),
y = rnorm(12, 10,2))
ggplot(mapping = aes(x,y)) +
geom_line(data = filter(my_df, grepl("English", lang)), aes(color=lang)) +
scale_color_brewer(NULL, palette = "Dark2") +
new_scale_colour() +
geom_line(data = filter(my_df, grepl("Spanish", lang)), aes(color=lang)) +
scale_color_brewer(palette = "Set1") +
guides(color = guide_legend(order = 1))
Created on 2021-04-11 by the reprex package (v1.0.0)
I have the following plot like below. It was created with this command:
library(ggplot2)
df <- data.frame(cond = factor(rep(c("A", "B"), each = 200)),
rating = c(rnorm(200), rnorm(200, mean=.8)))
ggplot(df, aes(x=rating, fill=cond)) +
geom_density(alpha = .3) +
xlab("NEW RATING TITLE") +
ylab("NEW DENSITY TITLE")
Now, I want to modify the legend title from cond into NEW LEGEND TITLE.
So, I just added the following line add the end of the above code:
+labs(colour="NEW LEGEND TITLE")
But it doesn't work. What's the right way to do it?
This should work:
p <- ggplot(df, aes(x=rating, fill=cond)) +
geom_density(alpha=.3) +
xlab("NEW RATING TITLE") +
ylab("NEW DENSITY TITLE")
p <- p + guides(fill=guide_legend(title="New Legend Title"))
(or alternatively)
p + scale_fill_discrete(name = "New Legend Title")
I didn't dig in much into this but because you used fill=cond in ggplot(),
+ labs(color='NEW LEGEND TITLE')
might not have worked. However it you replace color by fill, it works!
+ labs(fill='NEW LEGEND TITLE')
This worked for me in ggplot2_2.1.0
Since you have two densitys I imagine you may be wanting to set your own colours with scale_fill_manual.
If so you can do:
df <- data.frame(x=1:10,group=c(rep("a",5),rep("b",5)))
legend_title <- "OMG My Title"
ggplot(df, aes(x=x, fill=group)) + geom_density(alpha=.3) +
scale_fill_manual(legend_title,values=c("orange","red"))
None of the above code worked for me.
Here's what I found and it worked.
labs(color = "sale year")
You can also give a space between the title and the display by adding \n at the end.
labs(color = 'sale year\n")
Since in your code you used ggplot(data, fill= cond) to create the histogram you need to add the legend title by also using "fill" in the label section i.e. +labs(fill="Title name"). If you were using a different type of plot where the code was ggplot(data, colour= cond), then you could use +labs(colour= "Title Name"). In summary, the lab argument has to match the aes argument.
I have used + guides(fill=guide_legend("my awesome title")) to change the legend title on geom_bar plots but it did not seem to work for geom_point.
There's another very simple answer which can work for some simple graphs.
Just add a call to guide_legend() into your graph.
ggplot(...) + ... + guide_legend(title="my awesome title")
As shown in the very nice ggplot docs.
If that doesn't work, you can more precisely set your guide parameters with a call to guides:
ggplot(...) + ... + guides(fill=guide_legend("my awesome title"))
You can also vary the shape/color/size by specifying these parameters for your call to guides as well.
I am using a facet_wrap in my ggplot and none of the suggested solutions worked for me except ArnaudA's solution:
qplot(…) + guides(color=guide_legend(title="sale year"))
Just to add to the list (the other options here didn't work for me), you can also use the function update_labels for ggplot:
p <- ggplot(df, aes(x=rating, fill=cond)) +
geom_density(alpha=.3) +
xlab("NEW RATING TITLE") +
ylab("NEW DENSITY TITLE")
update_labels(p, list(colour="MY NEW LEGEND TITLE")
This will also allow you to change x- and y-axis labels, with separate lines:
update_labels(p, list(x="NEW X LABEL",y="NEW Y LABEL")
I noticed there are two ways to change/specify legend.title for ggboxplot():
library(ggpubr)
bxp.defaultLegend <- ggboxplot(ToothGrowth, x = "dose", y = "len",
color = "dose", palette = "jco")
# Solution 1, setup legend.title directly in ggboxplot()
bxp.legend <- ggboxplot(ToothGrowth, x = "dose", y = "len",
color = "dose", palette = "jco", legend.title="Dose (mg)")
# Solution 2: Change legend title and appearnace in ggboxplot() using labs() and theme() option:
plot1 <- bxp.defaultLegend + labs(color = "Dose (mg)") +
theme(legend.title = element_text(color = "blue", size = 10), legend.text = element_text(color = "red"))
ggarrange(list(bxp.legend, bxp.defaultLegend, plot1), nrow = 1, ncol = 3, common.legend = TRUE)
The code is modified based on the example from GitHub.
Adding this to the mix, for when you have changed the colors. This also worked for me in a qplot with two discrete variables:
p+ scale_fill_manual(values = Main_parties_color, name = "Main Parties")
The way i am going to tell you, will allow you to change the labels of legend, axis, title etc with a single formula and you don't need to use memorise multiple formulas. This will not affect the font style or the design of the labels/ text of titles and axis.
I am giving the complete answer of the question below.
library(ggplot2)
rating <- c(rnorm(200), rnorm(200, mean=.8))
cond <-factor(rep(c("A", "B"), each = 200))
df <- data.frame(cond,rating
)
k<- ggplot(data=df, aes(x=rating, fill=cond))+
geom_density(alpha = .3) +
xlab("NEW RATING TITLE") +
ylab("NEW DENSITY TITLE")
# to change the cond to a different label
k$labels$fill="New Legend Title"
# to change the axis titles
k$labels$y="Y Axis"
k$labels$x="X Axis"
k
I have stored the ggplot output in a variable "k". You can name it anything you like. Later I have used
k$labels$fill ="New Legend Title"
to change the legend. "fill" is used for those labels which shows different colours. If you have labels that shows sizes like 1 point represent 100, other point 200 etc then you can use this code like this-
k$labels$size ="Size of points"
and it will change that label title.
Alas, none of these solutions worked for me. I am working with output from brms::conditional_effects()
My solution required:
+ labs( fill = "New Title", colour = "New Title", labels = "New Title" )
Many people spend a lot of time changing labels, legend labels, titles and the names of the axis because they don't know it is possible to load tables in R that contains spaces " ". You can however do this to save time or reduce the size of your code, by specifying the separators when you load a table that is for example delimited with tabs (or any other separator than default or a single space):
read.table(sep = '\t')
or by using the default loading parameters of the csv format:
read.csv()
This means you can directly keep the name "NEW LEGEND TITLE" as a column name (header) in your original data file to avoid specifying a new legend title in every plot.
The only solution that works with me :
p + guides(fill=guide_legend("New title")
I'm using visual studio with R version 3.5.1 where I tried to plot legend to the graph.
f1 = function(x) {
return(x+1)}
x1 = seq(0, 1, by = 0.01)
data1 = data.frame(x1 = x1, f1 = f1(x1), F1 = cumtrapz(x1, f1(x1)) )
However, when I tried to plot it, it never give me a legend!
For example, I used the same code in this (Missing legend with ggplot2 and geom_line )
ggplot(data = data1, aes(x1)) +
geom_line(aes(y = f1), color = "1") +
geom_line(aes(y = F1), color = "2") +
scale_color_manual(values = c("red", "blue"))
I also looked into (How to add legend to ggplot manually? - R
) and many other websites in stackoverflo, and I have tried every single function in https://www.rstudio.com/wp-content/uploads/2016/11/ggplot2-cheatsheet-2.1.pdf
i.e.
theme(legend.position = "bottom")
scale_fill_discrete(...)
group
guides()
show.legend=TRUE
I even tried to use the original plot() and legend() function. Neither worked.
I thought there might be something wrong with the dataframe, but I split them(x2,f1,F1) apart, it still didn't work.
I thought there might be something wrong with IDE, but the code given by kohske acturally plotted legend!
d<-data.frame(x=1:5, y1=1:5, y2=2:6)
ggplot(d, aes(x)) +
geom_line(aes(y=y1, colour="1")) +
geom_line(aes(y=y2, colour="2")) +
scale_colour_manual(values=c("red", "blue"))
What's wrong with the code?
As far as I know, you only have X and Y variables in your aesthetics. Therefore there is no need for a legend. You have xlab and ylab to describe your two lines. If you want to have legends, you should put the grouping in the aesthetics, which might require recoding your dataset
d<- data.frame(x=c(1:5, 1:5), y=c(1:5, 2:6), colorGroup = c(rep("redGroup", 5),
rep("blueGroup", 5)))
ggplot(d, aes(x, y, color = colorGroup )) + geom_line()
This should give you two lines and a legend
This question is motivated by a previous post illustrating various ways to change how axes scales are plotted in a ggplot figure, from the default exponential notation to the full integer value (when ones axes values are very large). While I am able to convert the axes scales from exponential notation to full values, I am unclear how one would achieve the same goal for the values appearing in the legend.
While I understand that one can manually change the length of the legend scale with "scale_color..." or "scale_fill..." followed by the "limits" argument, this does not appear to be a solution to getting my legend values to show "6000000000" rather than "6e+09" (or "0" rather than "0e+00" for that matter).
The following example should suffice. My hope is someone can point out how to implement the 'scales' package to apply for legend scales rather than axes scales.
Thanks very much.
library(ggplot2)
library(scales)
Data <- data.frame(
pi = c(2,71,828,1828,45904,523536,2874713,52662497,757247093,6999595749),
e = c(3,14,159,2653,58979,311599,7963468,54418516,1590576171, 99),
face = 1:10)
p <- ggplot(data = Data, aes(x=face, y=e, colour = pi))
myplot <- p + geom_point() +
scale_y_continuous(labels = comma) +
scale_color_gradientn(colours = rainbow(2), limits=c(0,7000000000))
myplot
Use the Comma formatter in scale_color_gradientn by setting labels = comma e.g.:
p <- ggplot(data = Data, aes(x=face, y=e, colour = pi))
myplot <- p + geom_point() +
scale_y_continuous(labels = comma) +
scale_color_gradientn(colours = rainbow(2), limits=c(0,7000000000), labels = comma)
myplot
I want to produce a barplot overlayed with dots where both have separate legends. Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes(). As both are not mapped, no legend is produced.
1) How can I add a legend manually for both fill and size?
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5)
This is what I came up with: I used dummy mappings and modified the legend according to my needs afterwards. But this approach appears clumsy to me.
2) Is there a manual way to say: Add a legend with this title, these shapes, these colors etc.?
d <- data.frame(dummy1="d1",
dummy2="d2",
group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop, fill=dummy1, size=dummy2)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5) +
scale_fill_discrete(name="fill legend", label="fill label") +
scale_size_discrete(name="size legend", label="size label")
Above I mapped fill to dummy1. So I would expect scale_fill_discrete to alter this legend. But it appears to modify the size legend instead.
3) I am not sure what went wrong here. Any ideas?
I'm not sure why you say "Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes()". Is it something you're trying to do or is it something that you have to do given how ggplot works?
If it's the latter, one solution is as under -
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity",aes( fill="label")) +
geom_point(aes(size='labelsize')) +
scale_fill_manual(breaks = 'label', values = 'red')+
scale_size_manual(breaks = 'labelsize', values = 5)