How to add a legend to the multiple histograms with ggplot? - r

I am trying to add a legend to the graph but it doesn't work.
Do you have any ideas ?
Here is my code :
ggplot(data =stats_201507_AF ) +
geom_histogram(aes(gross_ind),fill="dodgerblue3", show.legend =T,bins=25)+
geom_histogram(aes(net_ind),fill="springgreen4",show.legend = T,bins=25) +
geom_histogram(aes(tax_ind),fill="gold2",show.legend = T, bins=25) +
xlab("Indices")+
scale_colour_manual(values=c("dodgerblue3","springgreen4","gold2"))
I wanted a description for every histogram with a corresponding colour.
Thanks a lot in advance

If you don't want to reshape your data, just do this:
ggplot(iris) +
geom_histogram(aes(x = Sepal.Length, fill = "Sepal.Length"),
position = "identity", alpha = 0.5) +
geom_histogram(aes(x = Sepal.Width, fill = "Sepal.Width"),
position = "identity", alpha = 0.5) +
scale_fill_manual(values = c(Sepal.Length = "blue",
Sepal.Width = "red"))
The key is that you need to map something to fill inside aes. Of course, reshaping your data to long format (and actually having a column to map to fill as a result) is usually preferable.

Related

ggplot2 custom legend with multiple geom overlays: guide_legend() confusion

I want to create a customized legend that distinguishes two plotted geoms using appropriate shape and color. I see that guide_legend() should be involved, but my legend is presented with both shapes overlayed one on the other for both components of the legend. What is the right way to build these individual legend components using distinct shapes and colors? Thank you.
library(dplyr)
df <- tibble(year=seq(2010,2020,1),
annualNitrogen=seq(100,200,10),
annualPotassium=seq(500,600,10))
ggplot() +
geom_point(data = df, aes(x = year, y = annualNitrogen, fill="green"), shape=24, color="green", size = 4) +
geom_point(data = df, aes(x = year, y = annualPotassium, fill="blue"), color="blue", shape=21, size = 4) +
guides(fill = guide_legend(override.aes = list(color=c("green", "blue"))),
shape = guide_legend(override.aes = list(shape=c(21, 24)))
) +
scale_fill_manual(name = 'cumulative\nmaterial',
values = c("blue"="blue" , "green"="green" ),
labels = c("potassium" , "nitrogen") ) +
theme_bw() +
theme(legend.position="bottom")
Here it helps to transform to "long" format which is more in line with how ggplot is designed to be used when separating factor levels within a single time series.
This allows us to map shape and color directly, rather than having to manually assign different values to multiple plotted series, like you do in your question.
library(tidyverse)
df %>%
pivot_longer(-year, names_to = "element") %>%
ggplot(aes(x=year, y = value, fill = element, shape = element, color = element)) +
geom_point(size = 4)+
scale_color_manual(values = c("green", "blue"))
Put your df into a long format that ggplot likes with tidyr::gather. You should only use one geom_point for this, you don't need separate geoms for separate variables. You can then specify the shape and variable in one call to geom_point.
df <- tibble(year=seq(2010,2020,1),
annualNitrogen=seq(100,200,10),
annualPotassium=seq(500,600,10))
df <- tidyr::gather(df, key = 'variable', value='value', annualNitrogen, annualPotassium)
ggplot(df) +
geom_point(aes(x = year, y = value, shape = variable, color = variable)) +
scale_color_manual(
name = 'cumulative\nmaterial',
values = c(
"annualPotassium" = "blue",
"annualNitrogen" = "green"),
labels = c("potassium" , "nitrogen")) +
guides(shape = FALSE)

Plotting multiple Pie Charts with label in one plot

I came across this question the other day and tried to re-create it for myself. ggplot, facet, piechart: placing text in the middle of pie chart slices
. My data is in a very similar format, but sadly the accepted answer did not help, hence why I am re posting.
I essentially want to create the accepted answer but with my own data, yet the issue I run into is that coord_polar does not support free scale. Using the first answer:
I tried it using the second version of the answer, with the ddplyr version, but I also do not get my desired output. Using the second answer:
Clearly none of these has the desired effect. I would prefer to create one as with size pie charts, but only showed four as an example, follows: .
This I did in excel, but with one legend, and no background grid.
Code
title<-c(1,1,2,2,3,3,4,4,5,5,6,6)
type<-c('A','B','A','B','A','B','A','B','A','B','A','B')
value<-c(0.25,0.75,0.3,0.7,0.4,0.6,0.5,0.5,0.1,0.9,0.15,0.85)
piec<-data.frame(title,type,value)
library(tidyverse)
p1<-ggplot(data = piec, aes(x = "", y = value, fill = type)) +
geom_bar(stat = "identity") +
geom_text(aes(label = value), position = position_stack(vjust = 0.5)) +
coord_polar(theta = "y")
#facet_grid(title ~ ., scales = "free")
p1
piec <- piec %>% group_by(title) %>% mutate(pos=cumsum(value)-0.5*value)
p2<-ggplot(data = piec) +
geom_bar(aes(x = "", y = value, fill = type), stat = "identity") +
geom_text(aes(x = "", y = pos, label = value)) +
coord_polar(theta = "y")
#facet_grid(Channel ~ ., scales = "free")
p2
You don't have to supply different y values for geom_text and geom_bar (use y = value for both of them). Next you have to specify position in geom_text. Finally, remove scales from facets.
library(ggplot2)
title<-c(1,1,2,2,3,3,4,4,5,5,6,6)
type<-c('A','B','A','B','A','B','A','B','A','B','A','B')
value<-c(0.25,0.75,0.3,0.7,0.4,0.6,0.5,0.5,0.1,0.9,0.15,0.85)
piec<-data.frame(title,type,value)
ggplot(piec, aes("", value, fill = type)) +
geom_bar(stat = "identity", color = "white", size = 1) +
geom_text(aes(label = paste0(value * 100, "%")),
position = position_stack(vjust = 0.5),
color = "white", size = 3) +
coord_polar(theta = "y") +
facet_wrap(~ title, ncol = 3) +
scale_fill_manual(values = c("#0048cc", "#cc8400")) +
theme_void()

ggplot2 - using two different color scales for same fill in overlayed plots

A very similar question to the one asked here. However, in that situation the fill parameter for the two plots are different. For my situation the fill parameter is the same for both plots, but I want different color schemes.
I would like to manually change the color in the boxplots and the scatter plots (for example making the boxes white and the points colored).
Example:
require(dplyr)
require(ggplot2)
n<-4*3*10
myvalues<- rexp((n))
days <- ntile(rexp(n),4)
doses <- ntile(rexp(n), 3)
test <- data.frame(values =myvalues,
day = factor(days, levels = unique(days)),
dose = factor(doses, levels = unique(doses)))
p<- ggplot(data = test, aes(x = day, y = values)) +
geom_boxplot( aes(fill = dose))+
geom_point( aes(fill = dose), alpha = 0.4,
position = position_jitterdodge())
produces a plot like this:
Using 'scale_fill_manual()' overwrites the aesthetic on both the boxplot and the scatterplot.
I have found a hack by adding 'colour' to geom_point and then when I use scale_fill_manual() the scatter point colors are not changed:
p<- ggplot(data = test, aes(x = day, y = values)) +
geom_boxplot(aes(fill = dose), outlier.shape = NA)+
geom_point(aes(fill = dose, colour = factor(test$dose)),
position = position_jitterdodge(jitter.width = 0.1))+
scale_fill_manual(values = c('white', 'white', 'white'))
Are there more efficient ways of getting the same result?
You can use group to set the different boxplots. No need to set the fill and then overwrite it:
ggplot(data = test, aes(x = day, y = values)) +
geom_boxplot(aes(group = interaction(day, dose)), outlier.shape = NA)+
geom_point(aes(fill = dose, colour = dose),
position = position_jitterdodge(jitter.width = 0.1))
And you should never use data$column inside aes - just use the bare column. Using data$column will work in simple cases, but will break whenever there are stat layers or facets.

Change the fill color of one of the dodged bar in ggplot

I want to change the order of the bar plot only for the last set, just to highlight it. I used scale_fill_manual(), but it didn't help much.
Here's my code:
x<-c(rep(c("Type1", "Type2"),4))
y<-c(4,5,6,7,3,4,5,2)
time<-c(2010,2010,2011,2011,2012,2012,2013,2013)
z<-data.frame(type = x, val=y, Time = time)
ggplot(data = z, aes(x=Time,y=val)) +
geom_bar(stat = "identity", position = "dodge", aes(fill=type))+
scale_fill_manual(values = c(rep(c("white", "gray51"),3),"white","red"))
Here's the output:
I want the graph to look like:
Is there any way I can do this? I would appreciate any help. I looked at change color of only one bar in ggplot but it doesn't seem to be about grouped data.
My general mantra is that ggplot is very good at plotting the data you give it. If you want it to plot something different, the easiest way is usually to modify your data.
z$type2 = as.character(z$type)
z$type2[z$type == "Type2" & z$Time == 2013] = "Type2 "
I added a sneaky extra space in "Type2 " for the row you want to highlight. It will be a distinct factor level and get its own color (and even be coerced into the a nice order using the alphabetical default). But it will appear the same in the legend label.
ggplot(data = z, aes(x=Time,y=val)) +
geom_bar(stat = "identity", position = "dodge", aes(fill=type2))+
scale_fill_manual(values = c("white", "gray50", "red"))
I thought that omitting the red from the legend would be difficult, but this answer showed me that all that is needed is to add breaks = c("Type1", "Type2") as an argument to scale_fill_manual.
What about highlighting the bar with a border. For example:
z$hi = with(z, ifelse(type=="Type2" & Time==2013, "Y","N"))
ggplot(data = z, aes(x=Time,y=val)) +
geom_bar(stat = "identity", position = "dodge",
aes(fill=type, colour=hi), size=1) +
scale_fill_manual(values=c("gray51","white")) +
scale_colour_manual(values=c(NA,"red")) +
guides(colour=FALSE)
UPDATE: In response to your comment: I think a line plot makes it easier to see the trends and the relationships between each type. For example:
ggplot(data = z, aes(x=Time,y=val,colour=type)) +
geom_line() +
geom_point() +
geom_point(data=z[z$hi=="Y",], aes(x=Time, y=val), size=4, pch=1,
colour=hcl(195,100,40), stroke=1) +
scale_y_continuous(limits=c(0,max(z$val))) +
theme_bw()
Easy to do it with the legend, though you may want to be cautious about throwing users off with the abrupt change in color. Simply add an additional category to your x variable to indicate where you want the highlighting.
x<- xHigh <- c(rep(c("Type1", "Type2"),4))
xHigh[length(xHigh)] <- "Type2_highlight"
myHighlight <- rep("No",length(x))
myHighlight[length(myHighlight)] <- "Yes"
y<-c(4,5,6,7,3,4,5,2)
time<-c(2010,2010,2011,2011,2012,2012,2013,2013)
z<-data.frame(type = x, xHigh = xHigh, val=y, Time = time, myHighlight = myHighlight)
ggplot(data = z, aes(x=Time,y=val)) +
geom_bar(stat = "identity", position = "dodge", aes(fill=xHigh))+
scale_fill_manual(values = c(Type1 = "white", Type2 = "gray51", Type2_highlight = "red"))
Another potential option for highlighting a particular bar is to draw a box around it, like so:
ggplot(data = z, aes(x=Time,y=val)) +
geom_bar(stat = "identity", position = "dodge", aes(fill=type))+
scale_fill_manual(values = c(Type1 = "white", Type2 = "gray51")) +
geom_bar(aes(linetype = xHigh)
, fill = NA
, stat = "identity", position = "dodge"
, col = "red"
, show.legend = FALSE) +
scale_linetype_manual(values = c(Type1 = 0
, Type2 = 0
, Type2_highlight = 1))
Hope that helps.

Taking away letters superimposed to points in ggplot legend [duplicate]

How can I can remove the letter 'a' from the legend generated by this code? If I remove the geom_text, then the 'a' letter will not show in the legend. I want to keep geom_text, though.
ggplot(data = iris, aes(x = Sepal.Length, y=Sepal.Width,
shape = Species, colour = Species)) +
geom_point() +
geom_text(aes(label = Species))
Set show.legend = FALSE in geom_text:
ggplot(data = iris,
aes(x = Sepal.Length, y = Sepal.Width, colour = Species,
shape = Species, label = Species)) +
geom_point() +
geom_text(show.legend = FALSE)
The argument show_guide changed name to show.legend in ggplot2 2.0.0 (see release news).
Pre-ggplot2 2.0.0:
With show_guide = FALSE like so...
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width , colour = Species,
shape = Species, label = Species ), size = 20) +
geom_point() +
geom_text(show_guide = FALSE)
We can use guide_legend(override.aes = aes(...)) to hide the 'a' in the legend.
Below is a short example of how you might use guide_legend()
library(ggrepel)
#> Loading required package: ggplot2
d <- mtcars[c(1:8),]
p <- ggplot(d, aes(wt, mpg)) +
geom_point() +
theme_classic(base_size = 18) +
geom_label_repel(
aes(label = rownames(d), fill = factor(cyl)),
size = 5, color = "white"
)
# Let's see what the default legend looks like.
p
# Now let's override some of the aesthetics:
p + guides(
fill = guide_legend(
title = "Legend Title",
override.aes = aes(label = "")
)
)
Created on 2019-04-29 by the reprex package (v0.2.1)
I had a similar problem. Simon's solution worked for me but a slight twist was required. I did not realise that I need to add "show_guide = F" to geom_text's arguments, rather than replace with it the existing arguments - which is what Simon's solution shows. For a ggplot2 noob like me this was not that obvious. A proper example would have used the OP's code and just added the missing argument like this:
..
geom_text(aes(label=Species), show_guide = F) +
..
Like Nick said
the following code would still produce the error:
geom_text(aes(x=1,y=2,label="",show_guide=F))
whereas:
geom_text(aes(x=1,y=2,label=""),show_guide=F)
outside the aes argument eliminates the a over the legend
I had a similar problem, with an 'a' appearing behind different coloured points I was trying to label with geom_text_repel. To remove the 'a', so that it would just show the point without the 'a' behind it, I had to add show.legend=FALSE as an argument in geom_text_repel.
Hope that makes sense to anyone who might be labouring with the same issue!
You can also use show.legend = FALSE in the arguments of geom_label_repel() to remove the "a" in the legend.
So, instead of
ggplot(d, aes(wt, mpg)) +
geom_point() +
theme_classic(base_size = 18) +
geom_label_repel(
aes(label = rownames(d), fill = factor(cyl)),
size = 5, color = "white"
)+ guides(
fill = guide_legend(
title = "Legend Title",
override.aes = aes(label = "")
)
)
you can do,
ggplot(d, aes(wt, mpg)) +
geom_point() +
theme_classic(base_size = 18) +
geom_label_repel(
aes(label = rownames(d), fill = factor(cyl)),
size = 5, color = "white",
show.legend = FALSE )

Resources