Multiple legends for a ggplot in R - r

I have seen existing treads but i couldnt correct my code. I have to divide the legend "Segmentation" into two different legends. One legend should be showing (Run,Walk) and other legend should be telling the StayPoint(Yes, No). Issue is that, all the legend values gets mixed up and comes under the same legend heading. Can anyone tell me about it ? Thank you !
ll_meanstt <- sapply(total_trajectory[1:2], mean)
sq_map2tt <- get_map(location = ll_meanstt, maptype = "roadmap", source
= "google", zoom = 21)
sisquoctt <-
setNames(data.frame(total_trajectory$tt_lon,total_trajectory$tt_lat,
total_trajectory$tt_ids, total_trajectory$Trajectory_Segmentation,
total_trajectory$tt_speed, Staypoint), c("lon", "lat", "LocationID",
"Segmentation", "SpeedMetersPerSecond", "Staypoint"));
ggmap(sq_map2tt) +
geom_point(data = sisquoctt, size = 12, aes(fill = Staypoint, shape =
Staypoint)) +
geom_point(data = sisquoctt, size = 8, aes(fill = Segmentation, shape =
Segmentation)) +
geom_line(data = sisquoctt, size = 3, aes(color =SpeedMetersPerSecond)) +
geom_label_repel (data = sisquoctt, aes(label = paste("",
as.character(LocationID), sep="")),
angle = 60, hjust = 2, color = "indianred3",size = 4)
lon lat LocationID Segmentation SpeedMetersPerSecond Staypoint
1 5.010633 47.29399 W5232 Walk 1.2 No
2 5.010643 47.29400 W5769 Walk 1.0 Yes
3 5.010716 47.29398 W5234 Run 1.5 No

The problem is you have called geom_point() twice for data in the same x, y location and assigned the same aesthetics (fill and shape) to both Staypoint and Segmentation, so ggplot is putting them in the same legend. If you specify fill = for one variable, and shape = for the other, they should go into different legends. Also, not all points have fill aesthetics, you need to either select shapes that do(shapes 21 - 25 have fill), or use color =, an aesthetic that all ggplot2 points have.
Example using color instead of fill
ggmap(sq_map2tt) +
geom_point(data = sisquoctt, size = 8, aes(color = Staypoint, shape = Segmentation)) +
geom_line(data = sisquoctt, size = 3, aes(color = SpeedMetersPerSecond))
another approach if you want to use fill instead of color
ggmap(sq_map2tt) +
geom_point(data = sisquoctt, size = 8, aes(fill = Staypoint, shape = Segmentation)) +
scale_shape_manual(values = c(21, 24) +
geom_line(data = sisquoctt, size = 3, aes(color = SpeedMetersPerSecond))

Related

How add legend in ggplot

I've written this code:
ggplot() +
geom_sf(aes(fill = dat$color_province)) +
theme_void() +
geom_point(data = producer,
aes(x = producer$MX, y = producer$MY), size = 3, col = "green", shape = 17, alpha = 0.6) +
geom_point(data = distribution,
aes(x = distribution$MX, y = distribution$MY), size = 4.5, col = "yellow", shape = 15) +
geom_point(data = retailer,
aes(x = retailer$MX, y = retailer$MY), size = 3, col = "slateblue", shape = 16) +
geom_point(data = Demand,
aes(x = Demand$MX, y = Demand$MY, size = Demand$De), col = "slateblue", shape = 17, alpha = 0.7) +
scale_fill_manual(values = c("#ff3333", "#ffc266"),
name = "Situation")
and now I want to add a legend to identify all points in my plot. How can I do it?
Here's an example on some data that everyone can run, since it uses built-in datasets that come with R. Here, I made color and size be dynamic aesthetics with the name of the series, and then mapped those series values to different aesthetic values using scale_*_manual, where * are the aesthetics you want to vary by series. This generates an automatic legend. By giving each aesthetic the same name ("source" here), ggplot2 knows to combine them into one legend.
(By the way, it's unnecessary and can lead to errors to refer to variables in ggplot2 aesthetics using the form retailer$MY; each geom will assume the variable is within the data frame referred to with data =, so you can just use MY in that case.)
ggplot() +
geom_point(data = mtcars,
aes(x = wt, y = mpg, color = "mtcars", size = "mtcars")) +
geom_point(data = attitude,
aes(x = rating/20, y = complaints/3, color = "attitude", size = "attitude")) +
scale_color_manual(values = c("mtcars" = "slateblue", "attitude" = "red"), name = "source") +
scale_size_manual(values = c("mtcars" = 3, "attitude" = 4.5), name = "source")

R ggplot modifying the legend to have custom elements

I have the following code:
library(ggplot2)
library(RColorBrewer)
colours <-brewer.pal(n = 3, name = 'Paired')
ids <- c("TestA", "TestB", "TestC")
bg <-c(23, 13, 15)
s1 <- c(21,15,17)
s2 <- c(27,25,11)
s3 <- c(24,14,18)
df <- data.frame(ids, bg, s1,s2,s3)
colors <- c("bgs"= "grey", "tid1"=colours[1], "tid2"=colours[2], "tid3"=colours[3])
ggplot(df, aes(x = ids)) +
geom_col(aes(y = bg, color = 'bgs'), fill = 'grey', size = 1, ) +
geom_point(aes(y = s1, color= 'tid1'), size = 10, group = 1) +
geom_point(aes(y = s2, color= 'tid2'), size = 10, group = 1) +
geom_point(aes(y = s3, color='tid3'), size = 10, group = 1)+
labs(x = "Year",
y = "(%)",
color = "Legend") +
scale_color_manual(values = colors)+
theme(legend.position="bottom")
This code produces the following graph:
The issue here is with the legend, i have used the fill = 'grey' in order to fill the bar chart in geom_col(). However you can see that this now produces a grey box over which the other elements in the legend are placed. Is there a way to show just the gray box for the bg data, and show colored circles only for the other data in the legend
Correct me if I'm wrong but I think you just want to remove the graph box in the legend that shows nothing? I'd ask in a comment but I don't have enough reputation yet :(
This is happening because you are specifying color = inside the aes() argument. The easiest way to get rid of this is to get rid of color = bgs.
Since you are working with a barchart, what color = does is add a 'border' of specified color around your graph. Whereas fill = is the color that actually fills in the color of the bars. So here is what the code and the graph would look like:
library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 3.6.3
library(RColorBrewer)
colours <-brewer.pal(n = 3, name = 'Paired')
ids <- c("TestA", "TestB", "TestC")
bg <-c(23, 13, 15)
s1 <- c(21,15,17)
s2 <- c(27,25,11)
s3 <- c(24,14,18)
df <- data.frame(ids, bg, s1,s2,s3)
colors <- c("bgs"= "grey", "tid1"=colours[1], "tid2"=colours[2], "tid3"=colours[3])
ggplot(df, aes(x = ids)) +
geom_col(aes(y = bg), fill = 'grey', size = 1) +
geom_point(aes(y = s1, color = 'tid1'), size = 10, group = 1) +
geom_point(aes(y = s2, color = 'tid2'), size = 10, group = 1) +
geom_point(aes(y = s3, color = 'tid3'), size = 10, group = 1)+
labs(x = "Year",
y = "(%)",
color = "Legend") +
scale_color_manual(values = colors)+
theme(legend.position="bottom")
Created on 2020-09-16 by the reprex package (v0.3.0)
There are other ways to do this too, including override.aes() (I think). If you are curious take a look at Hadley Wickham's book on ggplot2. There is a free pdf here: ggplot2 book
I think you would want to look at chapter 6 which covers the legends

How to modify and add an extra legend in a ggplot2 figure

I have data that looks like this:
example.df <- as.data.frame(matrix( c("height","fruit",0.2,0.4,0.7,
"height","veggies",0.3,0.6,0.8,
"height","exercise",0.1,0.2,0.5,
"bmi","fruit",0.2,0.4,0.6,
"bmi","veggies",0.1,0.5,0.7,
"bmi","exercise",0.4,0.7,0.8,
"IQ","fruit",0.4,0.5,0.6,
"IQ","veggies",0.3,0.5,0.7,
"IQ","exercise",0.1,0.4,0.6),
nrow=9, ncol=5, byrow = TRUE))
colnames(example.df) <- c("phenotype","predictor","corr1","corr2","corr3")
So basically three different correlations between 3x3 variables. I want to visualize the increase in correlations as follows:
ggplot(example.df, aes(x=phenotype, y=corr1, yend=corr3, colour = predictor)) +
geom_linerange(aes(x = phenotype,
ymin = corr1, ymax = corr3,
colour = predictor),
position = position_dodge(width = 0.5))+
geom_point(size = 3,
aes(x = phenotype, y = corr1, colour = predictor),
position = position_dodge(width = 0.5), shape=4)+
geom_point(size = 3,
aes(x = phenotype, y = corr2, colour = predictor),
position = position_dodge(width = 0.5), shape=18)+
geom_point(size = 3,
aes(x = phenotype, y = corr3, colour = predictor),
position = position_dodge(width = 0.5))+
labs(x=NULL, y=NULL,
title="Stackoverflow Example Plot")+
scale_colour_manual(name="", values=c("#4682B4", "#698B69", "#FF6347"))+
theme_minimal()
This gives me the following plot:
Problems:
Tthere is something wrong with the way the geom_point shapes are dodged with BMI and IQ. They should be all with on the line with the same colour, like with height.
How do I get an extra legend that can show what the circle, cross, and square represent? (i.e., the three different correlations shown on the line: cross = correlation 1, square = correlation 2, circle = correlation 3).
The legend now shows a line, circle, cross through each other, while just a line for the predictors (exercise, fruit, veggies) would suffice..
Sorry for the multiple issues, but adding the extra legend (problem #2) is the most important one, and I would be already very satisfied if that could be solved, the rest is bonus! :)
See if the following works for you? The main idea is to convert the data frame from wide to long format for the geom_point layer, and map correlation as a shape aesthetic:
example.df %>%
ggplot(aes(x = phenotype, color = predictor, group = predictor)) +
geom_linerange(aes(ymin = corr1, ymax = corr3),
position = position_dodge(width = 0.5)) +
geom_point(data = . %>% tidyr::gather(corr, value, -phenotype, -predictor),
aes(y = value, shape = corr),
size = 3,
position = position_dodge(width = 0.5)) +
scale_color_manual(values = c("#4682B4", "#698B69", "#FF6347")) +
scale_shape_manual(values = c(4, 18, 16),
labels = paste("correlation", 1:3)) +
labs(x = NULL, y = NULL, color = "", shape = "") +
theme_minimal()
Note: The colour legend is based on both geom_linerange and geom_point, hence the legend keys include both a line and a point shape. While it's possible to get rid of the second one, it does take some more convoluted code, and I don't think the plot would be much improved as a result...

How can I add specific, labeled points to a ggtern plot?

With ggplot2 I normally expect to be able to add a data point like so,
ggtern(df, aes(X, Y, Z, value = VALUE), aes(x, y, z)) +
geom_point(aes(fill = VALUE), size = 2, stroke = 0, shape = 21) +
scale_fill_gradient(low = "red",high = "yellow", guide = F) +
scale_color_gradient(low = "red",high = "yellow", guide = F) +
geom_point(aes(x = 10, y = 10, z = 50), shape = 21)
However, when using the ggtern package to generate a ternary diagram they are being inserted into the wrong locations (see example image) with the following warning:
Warning: Ignoring unknown aesthetics: z
This implies that ggplot2 is likely attempting to render the point and not ggtern. How can I add specific, labeled points to the ggtern plot?
It appears that there are two main points for this. The first is to create an annotation, although that might not be ideal since it is not as precise as a point. An example would be,
ggtern() +
annotate(geom = 'text',
x = c(0.5,1/3,0.0),
y = c(0.5,1/3,0.0),
z = c(0.0,1/3,1.0),
angle = c(0,30,60),
vjust = c(1.5,0.5,-0.5),
label = paste("Point",c("A","B","C")),
color = c("green","red",'blue')) +
theme_dark() +
theme_nomask()
The second option would be to create a new data frame and add that to the plot. While this has the advantage of having more control over the point, the disadvantage is that labeling will require additional work.
One possibility is to have a column that identifies the points you wish to label, in this example the column 'lab' and say I want to label points one and three:
df <- data.frame(x=c(10,20,30), y=c(15,25,35), z=c(75,55,35), VALUE=c(1,2,3), lab=c("One", "", "Three"))
Then geom_text or geom_label can be used to label those specific points, for example:
ggtern(df, aes(x, y, z, value = VALUE)) +
geom_point(aes(fill = VALUE), size = 2, stroke = 0, shape = 21) +
scale_fill_gradient(low = "red",high = "yellow", guide = F) +
scale_color_gradient(low = "red",high = "yellow", guide = F) +
geom_text(aes(label = lab), vjust=1)

How do I add a legend identifying the different geom_points in RStudio

I need help:
I cannot seem to add a legend to the following piece of code for ggplot R STDUIO
ggplot(Report_Data,
aes(x=Report_Data$Transect Point), show.legend = TRUE) +
geom_point(aes(y=Report_Data$Q1North),
shape = 6, size = 5, colour = label , show.legend = TRUE) +
geom_point(aes(y=Report_Data$Q1South),
shape = 4, size = 5, colour = label, show.legend = TRUE)+
labs(title="Density of Trees Species found North & South of the creek using two sampling methods",
y="Density in Tree Species Found", x="Transect Points",caption = "n7180853")+
geom_line(aes(y=Report_Data$Q1North, colour = Q1North),
colour = "green", size = 1, show.legend = TRUE)+
geom_line(aes(y=Report_Data$Q1South, color = Q1South),
colour = "pink4", size = 1, show.legend = TRUE)+ theme(legend.position = "right")
Hard to replicate without your data, but if you want to have your plot to have a legend for point shape, you need to include it within aes(...) for that layer. Similar with colour, or size, if you want. Then, add scale_shape_manual(...) or scale_colour_manual(...) as needed, specifying your specific values.
Here's a toy example using the default diamonds dataset.
data("diamonds")
ggplot(diamonds, aes(x = carat)) +
geom_point(data = diamonds[diamonds$cut == "Ideal",],
aes(y= price, shape = cut)) +
geom_point(data = diamonds[diamonds$cut == "Good",],
aes(y = price, shape = cut)) +
scale_shape_manual(values = c(6,4))

Resources