I'm making depth profiles with ggplot. Some of the lines are drawn between the variable points using geom_path but some are not, even when I try adding "group=1" (which was the only solution I've found for this problem). I'm doing multiple plots for different lakes and for each lake there is one or multiple variables not getting a line by using geom_path. For the code below only the Chl.a variable is not drawing a line, all the others do. What could this depend on?
I also tried geom_line instead but this only worked for some variables since the it draws the line following the x-axis, but I want the line to go vertically following the y-axis. Can I achieve this using geom_line since geom_path doesn't seem to work for all variables?
gs <- ggplot(goodspirit, aes(y=goodspirit$Depth.m)) +
geom_point(aes(x=Temp, colour= "Temp")) +
geom_path(aes(x=Temp, color = "Temp"), size=1.5) +
geom_point(aes(x=zDOmg, color ="z(DO mg/L)")) +
geom_path(aes(x=zDOmg, color ="z(DO mg/L)"), size=1.5) +
geom_point(aes(x=Chl.a, color ="Chl.a"), na.rm = TRUE) +
geom_path(aes(x=Chl.a, color ="Chl.a"), na.rm = TRUE, size=1.5) +
geom_point(aes(x=zN2O, color ="z(N2O.nM)"), na.rm = TRUE) +
geom_line(aes(x=zN2O, color ="z(N2O.nM)"), na.rm = TRUE, size=1.5) +
geom_point(aes(x=Sal.ppt, color ="Salinity.ppt"), na.rm = TRUE) +
geom_line(aes(x=Sal.ppt, color ="Salinity.ppt"), na.rm = TRUE, size=1.5)+
geom_point(aes(x=zph, color ="z(pH)")) +
geom_path(aes(x=zph, color ="z(pH)"), size=1.5) +
scale_x_continuous(position = "top", limits=c(-3,5), expand = c(0,0))+
scale_y_reverse(expand = c(0.05,0))+
ylab("Depth (m)") + xlab("x") + ggtitle("Good spirit lake") + labs(colour
= "Parameters") +
theme(plot.title = element_text(hjust = 0.5)) + theme_light()
gs
enter image description here
Related
I'm using ggplot2 for map plots in R. How do I add a legend entry for a layer without a scale, just for a uniform color:
geom_polygon(data = watercourses, fill = "#0055aa", alpha = .5)
I just want to have the item title "Watercourses" and a color block representing the correct fill color. How does this work? So far, I only figured out how I can include scales to the legend.
Thank you!
EDIT: Here's an example with the NC dataset.
Map without centroids in legend
library(sf)
library(ggplot2)
demo(nc)
nc_centroids <- st_centroid(nc)
ggplot(nc) +
geom_sf(aes(fill = BIR74)) +
scale_fill_gradient(low = "white", high = "red") +
geom_sf(data = nc_centroids, color = "blue") +
coord_sf()
Wrong usage of aes() for legend
ggplot(nc) +
geom_sf(aes(fill = BIR74)) +
scale_fill_gradient(low = "white", high = "red") +
geom_sf(data = nc_centroids, aes(color = "blue")) +
coord_sf()
Trying to add the centroids to the legend (based on the answer of r2evans, https://stackoverflow.com/a/75346358/4921339)
ggplot(nc) +
geom_sf(aes(fill = BIR74)) +
scale_fill_gradient(low = "white", high = "red") +
geom_sf(data = nc_centroids, aes(color = "County centroids")) +
scale_fill_manual(name = "Centroids", values = c("County centroids" = "blue"))
coord_sf()
Throws the following messages and an error:
Scale for fill is already present.
Adding another scale for fill, which will replace the existing scale.
Error: Continuous value supplied to discrete scale
In my original case I use sp package instead of sf, but the messages and error thrown in the end are the same.
I think I did not yet understand how things work here, unfortunately. Any helping hints are highly appreciated.
If you place your fill in an aes(.), it will create a legend. Since you want a specific color, I suggest also adding scale_fill_manual:
ggplot(mtcars[-(1:3),], aes(mpg, disp)) +
geom_point() +
# placeholder for your `geom_polygon`:
geom_point(data = mtcars[1:3,], aes(fill = "something"), alpha = 0.5) +
scale_fill_manual(name = "something else", values = c("something" = "#0055aa"))
Perhaps this to add your blue points:
ggplot(nc) +
geom_sf(aes(fill = BIR74)) +
scale_fill_gradient(low = "white", high = "red") +
geom_sf(data = transform(nc_centroids, col = "County centroids"), aes(colour = col)) +
coord_sf() +
scale_colour_manual(name = NULL, values = c("County centroids" = "blue"))
EDIT by #winnewoerp: Explanation of how it works, for those who have problems understanding it all (like me until now...):
Add an extra column to the data frame with a unique value to be used within the legend, this can be done e.g. using the transform() function like in the given example or like df$col <- "Column unique value" prior to ggplot().
The (sole?) advantage to using transform is that there is no need to alter the original data, which might affect other processes on it (outside of this image). One disadvantage to doing it this way is that one must hard-code the "Column unique value" in both the transform and the scale_colour_manual, below.
Use scale_colour_manual() to add the legend item (blue colour example):
scale_colour_manual(
name = "Legend title",
values = c("Column unique value" = "blue")
)
i want to add colors for my graph, i many ways to change the color but R still so confusing to me.
here is the code
ggplot(pie_chart_mutate, aes(x = "", y = per, fill = gender)) +
geom_col(color = "black") +
geom_text(aes(label = labels),
position = position_stack(vjust = 0.5)) +
guides(fill = guide_legend(title = "Gender")) +
coord_polar(theta = "y") +
scale_fill_brewer() +
theme_void()
i tried the scale_fill_manual but i don't really know how to apply it correctly.
here is the output of the ggplot
i want the colors to be in hex like #0f3443 and #34e89e
I have a Lorenz Curve graph that I filled by factor variables (male and female). This was done simply enough and overlapping was not an issue because there were only two factors.
Wage %>%
ggplot(aes(x = salary, fill = gender)) +
stat_lorenz(geom = "polygon", alpha = 0.65) +
geom_abline(linetype = "dashed") +
coord_fixed() +
scale_fill_hue() +
theme(legend.title = element_blank()) +
labs(x = "Cumulative Percentage of Observations",
y = "Cumulative Percentage of Wages",
title = "Lorenz curve by sex")
This provides the following graph:
However, when I have more than two factors (in this case four), the overlapping becomes a serious problem even if I use contrasting colors. Changing alpha does not do much at this stage. Have a look:
Wage %>%
ggplot(aes(x = salary, fill = Diploma)) +
stat_lorenz(geom = "polygon", alpha = 0.8) +
geom_abline(linetype = "dashed") +
coord_fixed() +
scale_fill_manual(values = c("green", "blue", "black", "white")) +
theme(legend.title = element_blank()) +
labs(x = "Cumulative Percentage of Observations",
y = "Cumulative Percentage of Wages",
title = "Lorenz curve by diploma")
At this point I've tried all different color pallettes, hues, brewers, manuals etc. I've also tried reordering the factors but as you can imagine, this did not work as well.
What I need is probably a single argument or function to stack all these areas on top of each other so they all have their distinct colors. Funny enough, I've failed to find what I'm looking for and decided to ask for help.
Thanks a lot.
The problem was solved by a dear friend. This was done by adding the categorical variables layer by layer, without defining the Lorenz Curve as a whole.
ggplot() + scale_fill_manual(values = wes_palette("GrandBudapest2", n = 4)) +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[3],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[3],]$Diploma), geom = "polygon") +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[4],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[4],]$Diploma), geom = "polygon") +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[2],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[2],]$Diploma), geom = "polygon") +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[1],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[1],]$Diploma), geom = "polygon") +
geom_abline(linetype = "dashed") +
coord_fixed() +
theme(legend.title = element_blank()) +
labs(x = "Cumulative Percentage of Observations",
y = "Cumulative Percentage of Wages",
title = "Lorenz curve by diploma")
Which yields:
legend <- c("score" = "black", "answer" = "red")
plot <- df_l %>% ggplot(aes(date, score, color = "score")) + geom_line() +
geom_vline(aes(xintercept = getDate(df_all %>% filter(name == List[5])), color = "answer"), linetype = "dashed", size = 1,) +
scale_color_manual(name = "Legend", values = legend) +
scale_x_date(labels = date_format("%m/%y"), breaks = date_breaks("months")) +
theme(axis.text.x = element_text(angle=45)) +
labs(title = "", x = "", y = "", colors = "Legend")
I get the result above and could not figure out how to resolve the problem that in the legend always both lines are mixed up. One legend should of course show the slim black line only and the other the dashed black line. Thanks in advance!
The issue you have is that geom_vline results in a legend item that is a vertical line and geom_line gives you a horizontal line item. One solution is to create the legend kind of manually by specifying the color= aesthetic in geom_line... but not in geom_vline. You can then create a kind of "dummy" geom with geom_blank that serves as a holding object for the aesthetics of color=. You can then specify the colors for both of those items via scale_color_manual. Here's an example:
set.seed(12345)
df <- data.frame(x=1:100,y=rnorm(100))
ggplot(df, aes(x,y)) + theme_bw() +
geom_line(aes(color='score')) +
geom_vline(aes(xintercept=4), linetype=2, color='red', show.legend = FALSE) +
geom_blank(aes(color='my line')) +
scale_color_manual(name='Legend', values=c('my line'='red','score'='black'))
That creates the one legend for color... but unfortunately "my line" is solid red, when it should be dashed. To fix that, you just apply the linetype= aesthetic in the same way.
ggplot(df, aes(x,y)) + theme_bw() +
geom_line(aes(color='score', linetype='score')) +
geom_vline(aes(xintercept=4), linetype=2, color='red', show.legend = FALSE) +
geom_blank(aes(color='my line', linetype='my line')) +
scale_linetype_manual(name='Legend', values=c('my line'=2,'score'=1)) +
scale_color_manual(name='Legend', values=c('my line'='red','score'='black'))
Using GapMinder data, I've made the plot below with a different regression line by continent:
Here is the code:
ggplot(gapminder_82,
aes(gdpPercap, lifeExp, color = continent)) +
geom_point() +
scale_x_log10() +
scale_color_brewer(palette = "Set2") +
geom_smooth(method = "lm", se = F)
The problem is that the lines aren't really visible. So I'd like to use 2 different color palettes from color brewer. The Pastel2 for the points, but I'd like to use "Dark2" for the lines. It would make the lines stand out.
How would I do it?
You can use a filled point shape for the points, allowing you to use a fill scale for the points and colour for the lines:
ggplot(gapminder_82,
aes(gdpPercap, lifeExp)) +
# Make the edge color for the points totally transparent
geom_point(aes(fill = continent), shape = 21, size = 3, colour = "#FFFFFF00") +
scale_x_log10() +
geom_smooth(aes(color = continent), method = "lm", se = F) +
scale_fill_brewer(palette = "Pastel2") +
scale_color_brewer(palette = "Dark2") +
theme_bw()
Result:
Even if separate color palettes were possible, I think it would lead to confusion since you would be mapping the same variable to two different colours.
How about adjusting the alpha of the points to increase the visibility of the lines?
gapminder_82 %>%
ggplot(aes(gdpPercap, lifeExp)) +
geom_point(aes(color = continent), alpha = 0.1) +
geom_smooth(method = "lm",
se = FALSE,
aes(color = continent)) +
scale_x_log10() +
scale_color_brewer(palette = "Set2") +
theme_bw()