How to edit legend description in ggplot without getting a second legend? - r

I had been trying to include a legend in my plot that shows the name of the months next to the line with its respective colour and shape but I can't figure it out.
I have tried using scale_color_hue() but I got two different legends
isop_temp <- ggplot(bio_all_data, aes(t_2m, isop)) +
geom_jitter(aes(shape = month, colour = month, fill = month)) +
geom_smooth(aes(group = month, colour = month), method='lm',
fullrange = T, se = F) +
theme_bw() +
ylim(0, 4.5) +
xlab('temperature °C')+
ylab('Isoprene[ppb]') +
theme(legend.position = "top") +
scale_color_hue(labels = c('February','March','April','May','June'))
And this is what I am getting. What am I missing?

Short answer: you need to add scale_shape() with the same labels.
The issue here is that you map one variable (month) to 3 aesthetics - color, shape and fill. That would give you one legend, but the addition of scale_color_hue() separates the mapping of color and shape.
To illustrate using a reproducible example - we will omit fill because only color is relevant to geom_point. This works as expected:
library(ggplot2)
iris %>%
ggplot(aes(Sepal.Length, Petal.Width)) +
geom_point(aes(color = Species, shape = Species))
Now we add scale_color_hue. We get a separate legend because the labels differ to the default labels used when we mapped to shape:
iris %>%
ggplot(aes(Sepal.Length, Petal.Width)) +
geom_point(aes(color = Species, shape = Species)) +
scale_color_hue(labels = LETTERS[1:3])
The simplest fix is to use the same labels in scale_shape. Alternatively you could dplyr::mutate() the data frame to add a column with month name and map to that instead.
iris %>%
ggplot(aes(Sepal.Length, Petal.Width)) +
geom_point(aes(color = Species, shape = Species)) +
scale_color_hue(labels = LETTERS[1:3]) +
scale_shape(labels = LETTERS[1:3])

Related

R ggplot: colour and fill arguments

I am new in R and just started to learn ggplot. I am so confused by the syntax, I thought the "color" and "fill" arguments should always follow color names or RGB specifications. But I've seen many cases where "color" and "fill" in aes() were assigned with variables, see the below example.
ggplot(faithfuld, aes(waiting, eruptions)) +
geom_raster(aes(fill = density))
I couldn't find an explanation of such use in [R documentation][1]. What does it mean? coloring by factor/grouping? if fill and color are assigned with variables, where should colors be specified? in scale_colour_manual?
Besides, I noticed that if specifying colors and/or transparency in aes(), the specified colors or transparency won't realise. For instance, in the below code, alpha = 0.3 is not working, I can change the alpha to any value, and the transparency will always be 0.5 in plotting. Why is that?
Also, I noticed that if I deleted fill or alpha in the aex(), the following "scale_fill_manual" wouldn't work. So is it true that "scale_fill_manual" is dependent on the geom_xx()?
p <- ggplot(dfcc) + geom_ribbon(aes(x = yr, ymax = ciupper, ymin = cilower, fill = "", alpha = 0.3)) +
scale_fill_manual(values = "blue", labels = "CI95%")
Sorry for so many questions, I am just so confused, and any help will be appreciated!
[1]: https://search.r-project.org/CRAN/refmans/ggplot2/html/aes_colour_fill_alpha.html
You can convey information about your data by mapping the aesthetics
in your plot to the variables in your dataset.
Please read Chapter 3 of R for Data Science when you got some time, it may answer your question. As examples, please see and observe the differences among these 3 set of code and their outputs:
1. Use Red as color:
iris |>
ggplot(aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(color = "red") +
theme_minimal() +
theme(panel.grid = element_blank())
You get:
2. Use Species as color:
iris |>
ggplot(aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(color = Species)) +
theme_minimal() +
theme(panel.grid = element_blank())
You get:
3. Modify Species with the color of your choice:
iris |>
ggplot(aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(color = Species)) +
theme_minimal() +
theme(panel.grid = element_blank()) +
scale_color_manual(values = c("red", "yellow", "purple"))
You get:
Hope this is helpful.

Customize ggplot2 legend with different variables

I have the following data about American and German teenagers' coding skills. I can easily display their bar plots, but I need to present the total number of teenagers from each country as well.
DF <- data.frame(code = rep(c("A","B","C"), each = 2),
Freq = c(441,121,700,866,45,95),
Country = rep(c("USA","Germany"),3),
Total = rep(c(1186,1082),3))
ggplot(DF, aes(code, Freq, fill = code)) + geom_bar(stat = "identity", alpha = 0.7) +
facet_wrap(~Country, scales = "free") +
theme_bw() +
theme(legend.position="none")
For example, instead of presenting the default legend for the code, I could replace it with the Country and the Total. Your help is appreciated
Here's what I would suggest:
library(dplyr); library(ggplot2)
DF %>%
add_count(Country, wt = Total) %>%
mutate(Country_total = paste0(Country, ": Total=", n)) %>%
ggplot(aes(code, Freq, fill = code)) + geom_bar(stat = "identity", alpha = 0.7) +
facet_wrap(~Country_total, scales = "free") +
theme_bw() +
theme(legend.position="none")
To do what you're requesting would take a different approach, since the data you're describing would not strictly be a ggplot2 legend (which explains how one of the variables is mapped to one of the graph aesthetics), rather it would be a table or annotation that is displayed alongside the plot. This could be generated separately and added to the figure using patchwork or grid packages.
For instance:
library(patchwork); library(gridExtra)
ggplot(DF, aes(code, Freq, fill = code)) + geom_bar(stat = "identity", alpha = 0.7) +
facet_wrap(~Country, scales = "free") +
theme_bw() +
theme(legend.position="none") +
tableGrob(count(DF, Country, wt = Total)) +
plot_layout(widths = c(2,1))

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()

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

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.

Resources