简体   繁体   中英

Add an extra shape with a label to a ggplot2 legend

I have a chart that I am making from two data sets. The large points reflect some data from one kind of device, the small circles represent data from another device. I'd really like the small circles to show up in the legend.

在此处输入图像描述

I recognize that I could rearrange this so that all of the points are in one row, and then I define size and shape carefully and get the small points in the legend that way. Somewhat like in this solution, but more complicated https://community.rstudio.com/t/adding-manual-legend-to-ggplot2/41651 I'd rather just add a small circle to the legend and call it "UVP" Is there a way to do this? Here's what I'd like to do, but manually in inkscape

在此处输入图像描述

Code to generate the first plot below:

Data for the plot

data1 <- structure(list(depth = c(10, 30, 50, 70, 90, 112.5, 137.5, 162.5, 
187.5, 225, 275, 325, 375, 425, 475, 525, 575, 625, 675, 725, 
775, 825, 875, 925, 975, 1050, 1150, 1250, 1350, 1450, 1550, 
1650, 1750, 1850, 1950, 2100, 2300, 2500), tot_flux2 = c(493.391307122024, 
88.4282572468022, 119.17354992495, 88.3420136880856, 55.6404426882139, 
23.1812327572326, 25.1107180682511, 27.4461496846079, 27.3648719079245, 
27.6454688644806, 29.8468118472875, 29.5852880741345, 26.9364421983894, 
29.599067987919, 28.0689550543691, 26.9607925818058, 22.6299786403629, 
21.8274647606067, 21.0185519382918, 18.2901098011584, 18.7644342604331, 
13.302886924911, 12.4073411713533, 10.70527639076, 10.3989475670089, 
11.1680615919731, 12.2697553616111, 14.9529491605114, 16.4925253769608, 
16.8444291402253, 14.6677394251565, 13.5512808553714, 14.6541054086481, 
15.2447655630027, 14.9427390135369, 12.2641023852846, 11.0432543841414, 
10.4113941660271)), row.names = c(NA, -38L), class = c("tbl_df", 
"tbl", "data.frame"))

data2 <- structure(list(Class = c("Organic", "Organic", "Organic", "Organic", 
"Organic", "Organic", "Organic", "Organic", "Organic", "Organic", 
"Organic", "Organic", "Organic"), Depth = c(69, 73, 148, 365, 
452, 965, 100, 100, 120, 120, 150, 159, 180), TrapID = c("4-22", 
"1-12", "1-12", "3-21", "3-21", "4-13", "2-14", "2-17", "3-15", 
"3-18", "2-17", "1-19", "3-18"), TrapType = c("cone", "cone", 
"cone", "net", "net", "net", "cone", "cone", "cone", "cone", 
"net", "cone", "net"), SampleType = c("plus.p", "plus.p", "plus.p", 
"plus.p", "plus.p", "plus.p", "top", "top", "top", "top", "top", 
"top", "top"), C_flux = c(1.86346195335968, 0.33708698993135, 
0.287766715331808, 0.342070253658537, 0.53058016195122, 0.162216257196462, 
0.237619178449906, 1.16823528498024, 0.82924427637051, 1.18838025889328, 
0.316782054545455, 0.420967185507246, 0.448680747228381), C_flux_umol = c(155.288496113307, 
28.0905824942792, 23.980559610984, 28.5058544715447, 44.215013495935, 
13.5180214330385, 19.8015982041588, 97.3529404150198, 69.1036896975425, 
99.0316882411067, 26.3985045454545, 35.0805987922705, 37.3900622690318
)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-13L), spec = structure(list(cols = list(Class = structure(list(), class = c("collector_character", 
"collector")), Depth = structure(list(), class = c("collector_double", 
"collector")), TrapID = structure(list(), class = c("collector_character", 
"collector")), TrapType = structure(list(), class = c("collector_character", 
"collector")), SampleType = structure(list(), class = c("collector_character", 
"collector")), C_flux = structure(list(), class = c("collector_double", 
"collector")), C_flux_umol = structure(list(), class = c("collector_double", 
"collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1), class = "col_spec"))

Making the plot

library(ggplot2)
library(tidyverse)
library(cowplot)

data1 %>%
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType),
             colour = "black", stroke = 1, size = 5, data = data2) +
  geom_point(aes(x = tot_flux2)) +
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = c(3, 4)) +
  ylab("Depth (m)") + xlab("Flux micro-mol/m^2/day") +
    guides(fill = guide_legend(override.aes = list(shape = 25))) +
  theme_cowplot()

It seems like you were not using size as a mapped aesthetic before, even though you added a scale. Hence, you could simply map the smaller points to the size scale. Example below:

data1 %>%
  ggplot(aes(y = depth))  + 
  scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, 
                 shape = TrapType),
             colour = "black", stroke = 1, size = 4, data = data2) +
  geom_point(aes(x = tot_flux2, size = "UVP")) +
  scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1) +
  ylab("Depth (m)") + xlab("Flux micro-mol/m^2/day") +
  guides(fill = guide_legend(override.aes = list(shape = 25))) +
  theme_cowplot()

在此处输入图像描述

You can remove the 'size' title by replacing the size scale with scale_size_manual(values = 1, name = "") .

Using your example data: (I removed the dependency on cowplot since I don't have it installed and didn't think it was relevant to your question)

library(tidyverse)
data1 %>%
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType),
             colour = "black", stroke = 1, size = 5, data = data2) +
  geom_point(aes(x = tot_flux2, color="black")) +
  scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = c(3, 4)) +
  ylab("Depth (m)") + xlab("Flux micro-mol/m^2/day")  +
  scale_color_identity(name = '', guide = 'legend',labels = c('UVP')) +
  guides(fill = guide_legend(override.aes = list(shape = 25), order=1),
         shape = guide_legend(order=1))

This produces the following plot:

在此处输入图像描述

Edit:

explanation:

geom_point(aes(x = tot_flux2, color="black")) 

Uses the 'color``argument in an call to aes with the value `"black"

scale_color_identity(name = '', guide = 'legend',labels = c('UVP'))

Tells ggplot that the colour aesthetic is used in the identity way (ie "black" has the colour "black") and specifies the empty legend title and value for the legend.

guides(fill = guide_legend(override.aes = list(shape = 25), order=1),
     shape = guide_legend(order=1))

Uses the order= argument in the call to guide_legend to bring the guides in the order as in your inkscape image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM