I've been searching the answer for two days and still can't find how to do this. The closest cases I found here and here. But the former has no points on the plots and the latter has no answer. Without much ado, how to add points to my legend?
This is my data:
Year <- c(2003:2020)
TheData <- c(72.6, 72.7, 72.6, 72.5, 72.4, 72.1, 71.8, 71.7, 71.8, 72.3, 72.7,
72.9, 73.1, 73.3, 73.8, 74.7, 75.7, 77.1)
Lower <- c(72.33316, 72.05961, 71.8218, 71.62303, 71.46657, 71.35567, 71.29362,
71.28368, 71.32915, 71.43331, 71.59947, 71.83096, 72.13113, 72.50333,
72.95092, 73.47728, 74.08581, 74.77989)
Upper <- c(73.46626, 73.24078, 73.05676, 72.91817, 72.82899, 72.79323, 72.81489,
72.89794, 73.04639, 73.26418, 73.55528, 73.92363, 74.37315, 74.90775,
75.53132, 76.24776, 77.06094, 77.97473)
Model <- c(72.89971, 72.65020, 72.43928, 72.27060, 72.14778, 72.07445, 72.05425,
72.09081, 72.18777, 72.34874, 72.57738, 72.87730, 73.25214, 73.70554,
74.24112, 74.86252, 75.57337, 76.37731)
MyDF <- data.frame(Year, TheData, Lower, Upper, Model)
This is my code:
library("ggplot2")
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model", fill = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom")
This is my plot.
If you want to get a legend you have to map on an aesthetic, e.g. you could map on the shape aes to get a legend for your points too:
library("ggplot2")
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData, shape = "TheData"), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom") +
labs(shape = "")
If somebody is interested to move the legend to free space on the plot there is an obvious way to do so:
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData, shape = "TheData"), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom") +
labs(shape = "") +
theme(legend.position = c(.4, .7))
But the legend appears stacked:
Adding + guides(color = guide_legend(nrow = 1)) does not work:
My colleague have proposed to add legend.box = "horizontal". This code works:
ggplot(MyDF, aes(x = Year, y = TheData)) +
geom_point(aes(y = TheData, shape = "TheData"), size = 2.5) +
geom_line(aes(x = Year, y = Model, color = "Model")) +
geom_ribbon(aes(ymin = Lower, ymax = Upper, x = Year,
fill = "Confidence Interval"), alpha = 0.15) +
scale_colour_manual(
name = "", values = c("Confidence Interval" = "transparent",
"Model" = "black")) +
scale_fill_manual(
name = "", values = c("Confidence Interval" = "grey12",
"Model" = "transparent")) +
theme(legend.position = "bottom") +
labs(shape = "") +
theme(legend.position = c(.4, .7), legend.box = "horizontal") +
guides(color = guide_legend(nrow = 1))
The plot looks like this:
Still, I wonder why the legend appears in different boxes and how to put it together?
Related
I am trying to overlap a shp layer on a map created with ggplot, when I plot the two graphs are independent, what do you suggest me to do to overlap both layers?
data.shape<-readOGR(dsn="departamentos",layer="DEPARTAMENTOS")
ggplot()+
geom_tile(data = tx_trend, aes(x = longitude, y = latitude, fill = slope))+
scale_fill_gradientn(colors = rev(pals::linearlhot(100)), name = "ºC/10y", limits = c(0.1,0.5)) +
#scale_fill_gradientn(colors = (pals::isol(100)), name = "ºC/10y", limits = c(0.1,0.45)) +
# geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
size = 0.7, show.legend = T) +
scale_color_manual(values = c("black"), name = "")+
coord_fixed(1.3)+
xlab("Longitude") + ylab("Latitude")+
labs(title = "Decadal trend Summer",
subtitle = "(1981-2016)",
caption = "")+
theme_bw() +
guides(fill = guide_colourbar(barwidth = 9, barheight = 0.5, title.position="right"))+
theme(legend.position = "bottom")
Difficult without a reproducible example but I give it a try! So here are my suggestions:
Install the 'sf' package with install.packages("sf") and load library with library(sf)
Import your layer in sf format with st_read():
data.shape <- st_read(dsn="departamentos", layer="DEPARTAMENTOS")
Use the dedicated geom_sf() to plot your shape on your tile and point layers. You just need to add the following line of code in the ggplot() chunk of code:
geom_sf(data = st_geometry(data.shape), fill = NA, color = "red") +
coord_sf(default_crs = sf::st_crs(4326)) +
So I suggest:
ggplot()+
geom_tile(data = tx_trend, aes(x = longitude, y = latitude, fill = slope))+
scale_fill_gradientn(colors = rev(pals::linearlhot(100)), name = "ºC/10y", limits = c(0.1,0.5)) +
#scale_fill_gradientn(colors = (pals::isol(100)), name = "ºC/10y", limits = c(0.1,0.45)) +
# geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
geom_point(data = filter(tx_trend, sign < 0.01),aes(x = longitude, y = latitude, color = "Sign. trend \n p-value <0.01"),
size = 0.7, show.legend = T) +
geom_sf(data = st_geometry(data.shape), fill = NA, color = "red") + # ADDED HERE
coord_sf(default_crs = sf::st_crs(4326)) + # ADDED HERE
scale_color_manual(values = c("black"), name = "")+
coord_fixed(1.3)+
xlab("Longitude") + ylab("Latitude")+
labs(title = "Decadal trend Summer",
subtitle = "(1981-2016)",
caption = "")+
theme_bw() +
guides(fill = guide_colourbar(barwidth = 9, barheight = 0.5, title.position="right"))+
theme(legend.position = "bottom")
i would like to have help with my graph. I would like to be able to change the graph representation algorithm (LGL or other) but I can't. How can I do it? have tried several options that do not work...
library(NetworkToolbox)
library(dplyr)
library(igraph)
library(ggplot2)
library(ggnetwork)
M1 <- as_tibble(replicate(21,sample(1:3,100,rep=TRUE)))
colnames(M1) <- c("1st", "2nd", "3th", "4th", "5th", "6th","7th","8th","9th","10th",
"11th","12th","13th","14th","15th","16th","17th","18th","19th",
"20th","21th")
M2 <- as.matrix(round(cor(M1[,],method ="kendall"),2))
gr4ph <- graph.adjacency(M2, mode = "undirected",weight=TRUE)
MAST <- MaST(M2, normal = False)
gr4ph <- graph.adjacency(MAST , mode = "lower",weight=TRUE)
ggplot(gr4ph, aes(x = x, y = y, xend = xend, yend = yend)) +
geom_edges(color = "grey", alpha = 1) +
geom_nodes(aes(color = name)) + theme_blank() +
geom_nodetext(aes(label = name), color = "black") +
geom_edgetext(aes(label = weight))+
theme(legend.position = "none")
You can use two solution. The layout argument is the key of the graph's representation :
The following exemple are coded with "Large graph layout"
With ggplot :
ggplot(gr4ph1, aes(x = x, y = y, xend = xend, yend = yend),layout = layout_with_lgl(gr4ph1))+
geom_edges(color = "grey", alpha = 1,size=1.5,) +
geom_nodes(aes(color = name), size = 3) + theme_blank() +
geom_nodetext(aes(label = name), color = "black", size = 3) +
geom_edgetext(aes(label = weight), size = 3,label.padding=unit(0.01, "lines"))+
theme(legend.position = "none")
With ggraph :
ggraph(gr4ph, layout = "lgl") +
geom_edge_link(aes(label = weight), angle_calc = 'along',label_dodge = unit(2.5, 'mm')) +
geom_node_point(aes(size=3,color= name)) +
theme(legend.position = "none")+
geom_node_text(aes(label = name), repel = TRUE)
I created the following plot using ggplot:
y1 <- runif(20,-2,7)
y2 <- c(-0.30306664,0.14744265 , 0.43857131 ,-0.04536794 ,-1.41432016,0.51887010 , 6.34925495 , 2.82511601 , 2.84251791, 4.05300569,-2.34208042, -0.29278747 , 0.49661933 , 0.75099908 ,1.12097713,2.72244949 , 2.23933230 , 1.86667714 , 2.17540024 , 7.56568823)
x <- 2001:2020
ggplot() +
geom_rect(aes(xmin=2006.90, xmax=2009.15,ymin=-Inf,ymax=10, fill='blue'), alpha= 0.4)+geom_rect(aes(xmin=2019.80, xmax=Inf,ymin=-Inf,ymax=10, fill='orange'), alpha= 0.3)+geom_rect(aes(xmin=2009.90, xmax=2013.15,ymin=-Inf,ymax=10, fill="lightgreen"), alpha= 0.4)+
geom_line(aes(x=x,y = y1),colour="black")+geom_line(aes(x=x,y = y2),colour="red")+
geom_point(aes(x=x,y = y1),col="black")+
geom_point(aes(x=x,y = y2),col="red")+
theme_classic()+
scale_fill_manual(name="",values = c("lightblue","lightgreen","orange"),labels=c(" R","k","C"))+theme(legend.position = "bottom")+ theme(axis.text.x = element_text(angle = 90))+geom_hline(yintercept = 0, color="black", size=1)
I have one legend to explain the content of the rectangles of the graph, but I need to add another legend to explain the two lines which are black and red. I wondered how to add another legend with a different position than the one that already exists to explain the names of the lines?
Can anyone help?
Move color inside aes, add scale_color_identity to get the right colors and to set the labels for the legend:
library(ggplot2)
ggplot() +
geom_rect(aes(xmin = 2006.90, xmax = 2009.15, ymin = -Inf, ymax = 10, fill = "blue"), alpha = 0.4) +
geom_rect(aes(xmin = 2019.80, xmax = Inf, ymin = -Inf, ymax = 10, fill = "orange"), alpha = 0.3) +
geom_rect(aes(xmin = 2009.90, xmax = 2013.15, ymin = -Inf, ymax = 10, fill = "lightgreen"), alpha = 0.4) +
geom_line(aes(x = x, y = y1, colour = "black")) +
geom_line(aes(x = x, y = y2, colour = "red")) +
geom_point(aes(x = x, y = y1, col = "black")) +
geom_point(aes(x = x, y = y2, col = "red")) +
scale_color_identity(name = NULL, labels = c(black = "Label 1", red = "Label 2"), guide = "legend") +
theme_classic() +
scale_fill_manual(name = "", values = c("lightblue", "lightgreen", "orange"), labels = c(" Rezession", "krise", "Corona 2020-")) +
theme(legend.position = "bottom") +
theme(axis.text.x = element_text(angle = 90)) +
geom_hline(yintercept = 0, color = "black", size = 1)
My code with the following output (below in the picture) calculates the average price of the neighbourhood groups.
Beside the mean I also want to add the median price label. How should I add this information to the graph?
{r }
p.nbr <- ny_explor %>%
group_by(neighbourhood_group) %>%
summarise(price = round(mean(price), 2))
ggplot(ny_explor, aes(price)) +
geom_histogram(bins = 30, aes(y = ..density..), fill = "darkslategrey") +
geom_density(alpha = 0.2, fill = "darkslategrey") +
theme_bw() +
ggtitle("Distribution of price by neighbourhood groups",
subtitle = expression("With" ~'log'[10] ~ "transformation of x-axis")) +
geom_vline(data = p.nbr, aes(xintercept = price), size = 2, linetype = 3) +
geom_text(data = p.nbr,y = 1.5, aes(x = price + 1400, label = paste("Mean = ",price)), color = "saddlebrown", size = 4) +
facet_wrap(~neighbourhood_group) +
scale_x_log10()
Though it would have been easier if you could include some sample data, yet it is advised that your existing code may be modified like this, which may work. If not, please incluide some sample data
p.nbr <- ny_explor %>%
group_by(neighbourhood_group) %>%
summarise(price_mean = round(mean(price), 2),
price_median = median(price))
ggplot(ny_explor, aes(price_mean)) +
geom_histogram(bins = 30, aes(y = ..density..), fill = "darkslategrey") +
geom_density(alpha = 0.2, fill = "darkslategrey") +
theme_bw() +
ggtitle("Distribution of price by neighbourhood groups",
subtitle = expression("With" ~'log'[10] ~ "transformation of x-axis")) +
geom_vline(data = p.nbr, aes(xintercept = price_mean), size = 2, linetype = 3) +
geom_text(data = p.nbr,y = 1.5, aes(x = price_mean + 1400, label = paste("Mean = ",price_mean),
"/nMedian = ", price_median), color = "saddlebrown", size = 4) +
facet_wrap(~neighbourhood_group) +
scale_x_log10()
I wanted to comment on the following doubt.
Using this code:
Plot<-data.frame(Age=c(0,0,0,0,0),Density=c(0,0,0,0,0),Sensitivity=c(0,0,0,0,0),inf=c(0,0,0,0,0),sup=c(0,0,0,0,0),tde=c(0,0,0,0,0))
Plot[1,]<-c(1,1,0.857,0.793,0.904,0.00209834)
Plot[2,]<-c(1,2,0.771 ,0.74,0.799,0.00348286)
Plot[3,]<-c(1,3,0.763 ,0.717,0.804,0.00577784)
Plot[4,]<-c(1,4,0.724 ,0.653,0.785,0.00504161)
Plot[5,]<-c(2,1,0.906,0.866,0.934,0.00365742)
Plot[6,]<-c(2,2,0.785 ,0.754,0.813,0.00440399)
Plot[7,]<-c(2,3,0.660,0.593,0.722,0.00542849)
Plot[8,]<-c(2,4,0.544,0.425,0.658,0.00433052)
names(Plot)<-c("Age","Mammographyc density","Sensitivity","inf","sup","tde")
Plot$Age<-c("50-59","50-59","50-59","50-59","60-69","60-69","60-69","60-69")
Plot$Density<-c("Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense","Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense")
levels(Plot$Age)<-c("50-59","60-69")
levels(Plot$Density)<-c("Almost entirely fat","Scattered fibroglandular density","Heterogeneously dense","Extremely dense")
pd <- position_dodge(0.2) #
Plot$Density <- reorder(Plot$Density, 1-Plot$Sensitivity)
ggplot(Plot, aes(x = Density, y = 100*Sensitivity, colour=Age)) +
geom_errorbar(aes(ymin = 100*inf, ymax = 100*sup), width = .1, position = pd) +
geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
geom_point(position = pd, size = 4)+
scale_y_continuous(expand = c(0, 0),name = 'Sensitivity (%)',sec.axis = sec_axis(~./5, name = 'Breast cancer detection rate (per 1000 mammograms)', breaks = c(0,5,10,15,20),
labels = c('0‰',"5‰", '10‰', '15‰', '20‰')), limits = c(0,100)) +
geom_line(position = pd, aes(x = Density, y = tde * 5000, colour = Age, group = Age), linetype = c("dashed"), data = Plot) +
geom_point(shape=18,aes(x = Density, y = tde * 5000, colour = Age, group = Age), position = pd, size = 4) +
theme_light() +
scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
theme(legend.position="bottom") + guides(colour = guide_legend(), size = guide_legend(),
shape = guide_legend())
I have made the following graph,
in which the axis on the left is the scale of the circles and the axis on the right is the scale of the diamonds. The fact is that I would like to have a legend approximately like this:
But it is impossible for me, I have tried suggestions of other threads like scale_shape and different commands in guides but I have not got success. I just want to make clear the difference in what shape and color represent.
Would someone know how to help me?
Best regards,
What you should do is a panel plot to avoid the confusion of double axes:
library(dplyr)
library(tidyr)
Plot %>%
gather(measure, Result, Sensitivity, tde) %>%
ggplot(aes(x = Density, y = Result, colour=Age)) +
geom_errorbar(aes(ymin = inf, ymax = sup), width = .1, position = pd,
data = . %>% filter(measure == "Sensitivity")) +
geom_line(aes(group = Age), position = pd, linetype = "dashed") +
geom_point(position = pd, size = 4)+
# scale_y_continuous(expand = c(0, 0), limits = c(0, 1)) +
scale_y_continuous(labels = scales::percent) +
facet_wrap(~measure, ncol = 1, scales = "free_y") +
theme_light() +
scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
theme(legend.position="bottom")
But to do what you asked, you problem is that you have only 1 non-positional aesthetic mapped so you cannot get more than one legend. To force a second legend, you need to add a second mapping. It can be a dummy mapping that has no effect, as below we map alpha but then manually scale both levels to 100%. This solution is not advisable because, as you have done in your example of a desired legend, it is easy to mix up the mappings and have your viz tell a lie by mislabeling which points are sensitivity and which are detection rate.
ggplot(Plot, aes(x = Density, y = 100*Sensitivity, colour=Age, alpha = Age)) +
geom_errorbar(aes(ymin = 100*inf, ymax = 100*sup), width = .1, position = pd) +
geom_line(position = pd, aes(group = Age), linetype = c("dashed")) +
geom_point(position = pd, size = 4)+
scale_y_continuous(expand = c(0, 0),name = 'Sensitivity (%)',sec.axis = sec_axis(~./5, name = 'Breast cancer detection rate (per 1000 mammograms)', breaks = c(0,5,10,15,20),
labels = c('0‰',"5‰", '10‰', '15‰', '20‰')), limits = c(0,100)) +
geom_line(position = pd, aes(x = Density, y = tde * 5000, colour = Age, group = Age), linetype = c("dashed"), data = Plot) +
geom_point(shape=18,aes(x = Density, y = tde * 5000, colour = Age, group = Age), position = pd, size = 4) +
theme_light() +
scale_color_manual(name="Age (years)",values = c("50-59"= "grey55", "60-69" = "grey15")) +
scale_alpha_manual(values = c(1, 1)) +
guides(alpha = guide_legend("Sensitivity"),
color = guide_legend("Detection Rate", override.aes = list(shape = 18))) +
theme(legend.position="bottom")