简体   繁体   English

将图例添加到 ggplot2 线图

[英]Add legend to ggplot2 line plot

I have a question about legends in ggplot2.我对 ggplot2 中的图例有疑问。 I managed to plot three lines in the same graph and want to add a legend with the three colors used.我设法在同一张图中绘制了三条线,并想添加一个使用三种颜色的图例。 This is the code used这是使用的代码

library(ggplot2)

## edit from original post - removed lines that downloaded data from broken link. Data snippet now below.
## Here a subset as used by [Brian Diggs in their answer](https://stackoverflow.com/a/10355844/7941188)
datos <- structure(list(fecha = structure(c(1317452400, 1317538800, 1317625200, 1317711600, 1317798000, 1317884400, 1317970800, 1318057200, 1318143600, 1318230000, 1318316400, 1318402800, 1318489200, 1318575600, 1318662000, 1318748400, 1318834800, 1318921200, 1319007600, 1319094000), class = c("POSIXct", "POSIXt"), tzone = ""), TempMax = c(26.58, 27.78, 27.9, 27.44, 30.9, 30.44, 27.57, 25.71, 25.98, 26.84, 33.58, 30.7, 31.3, 27.18, 26.58, 26.18, 25.19, 24.19, 27.65, 23.92), TempMedia = c(22.88, 22.87, 22.41, 21.63, 22.43, 22.29, 21.89, 20.52, 19.71, 20.73, 23.51, 23.13, 22.95, 21.95, 21.91, 20.72, 20.45, 19.42, 19.97, 19.61), TempMin = c(
  19.34, 19.14, 18.34, 17.49, 16.75, 16.75, 16.88, 16.82, 14.82, 16.01, 16.88, 17.55, 16.75, 17.22, 19.01,
  16.95, 17.55, 15.21, 14.22, 16.42
)), .Names = c(
  "fecha", "TempMax",
  "TempMedia", "TempMin"
), row.names = c(NA, 20L), class = "data.frame")

ggplot(data = datos, aes(x = fecha, y = TempMax, colour = "1")) +
  geom_line(colour = "red") +
  geom_line(aes(x = fecha, y = TempMedia, colour = "2"), colour = "green") +
  geom_line(aes(x = fecha, y = TempMin, colour = "2"), colour = "blue") +
  scale_y_continuous(limits = c(-10, 40)) +
  scale_colour_manual(values = c("red", "green", "blue")) +
  labs(title = "TITULO", x = NULL, y = "Temperatura (C)") 

I'd like to add a legend with the three colours used and the name of the variable (TempMax,TempMedia and TempMin).我想添加一个图例,其中包含使用的三种颜色和变量名称(TempMax、TempMedia 和 TempMin)。 I have tried scale_colour_manual , but can't find the exact way.我试过scale_colour_manual ,但找不到确切的方法。

Since@Etienne asked how to do this without melting the data (which in general is the preferred method, but I recognize there may be some cases where that is not possible), I present the following alternative.由于@Etienne询问如何在不融化数据的情况下执行此操作(这通常是首选方法,但我认识到在某些情况下可能无法做到这一点),我提出了以下替代方案。

Start with a subset of the original data:从原始数据的子集开始:

datos <-
structure(list(fecha = structure(c(1317452400, 1317538800, 1317625200, 
1317711600, 1317798000, 1317884400, 1317970800, 1318057200, 1318143600, 
1318230000, 1318316400, 1318402800, 1318489200, 1318575600, 1318662000, 
1318748400, 1318834800, 1318921200, 1319007600, 1319094000), class = c("POSIXct", 
"POSIXt"), tzone = ""), TempMax = c(26.58, 27.78, 27.9, 27.44, 
30.9, 30.44, 27.57, 25.71, 25.98, 26.84, 33.58, 30.7, 31.3, 27.18, 
26.58, 26.18, 25.19, 24.19, 27.65, 23.92), TempMedia = c(22.88, 
22.87, 22.41, 21.63, 22.43, 22.29, 21.89, 20.52, 19.71, 20.73, 
23.51, 23.13, 22.95, 21.95, 21.91, 20.72, 20.45, 19.42, 19.97, 
19.61), TempMin = c(19.34, 19.14, 18.34, 17.49, 16.75, 16.75, 
16.88, 16.82, 14.82, 16.01, 16.88, 17.55, 16.75, 17.22, 19.01, 
16.95, 17.55, 15.21, 14.22, 16.42)), .Names = c("fecha", "TempMax", 
"TempMedia", "TempMin"), row.names = c(NA, 20L), class = "data.frame")

You can get the desired effect by (and this also cleans up the original plotting code):您可以通过以下方式获得所需的效果(这也清理了原始绘图代码):

ggplot(data = datos, aes(x = fecha)) +
  geom_line(aes(y = TempMax, colour = "TempMax")) +
  geom_line(aes(y = TempMedia, colour = "TempMedia")) +
  geom_line(aes(y = TempMin, colour = "TempMin")) +
  scale_colour_manual("", 
                      breaks = c("TempMax", "TempMedia", "TempMin"),
                      values = c("red", "green", "blue")) +
  xlab(" ") +
  scale_y_continuous("Temperatura (C)", limits = c(-10,40)) + 
  labs(title="TITULO")

The idea is that each line is given a color by mapping the colour aesthetic to a constant string.这个想法是通过将colour美学映射到一个常量字符串来为每条线赋予一种颜色。 Choosing the string which is what you want to appear in the legend is the easiest.选择要在图例中出现的字符串是最简单的。 The fact that in this case it is the same as the name of the y variable being plotted is not significant;在这种情况下,它与正在绘制的y变量的名称相同这一事实并不重要; it could be any set of strings.它可以是任何一组字符串。 It is very important that this is inside the aes call;这在aes调用中非常重要; you are creating a mapping to this "variable".您正在创建到此“变量”的映射。

scale_colour_manual can now map these strings to the appropriate colors. scale_colour_manual现在可以将这些字符串映射到适当的颜色。 The result is结果是在此处输入图像描述

In some cases, the mapping between the levels and colors needs to be made explicit by naming the values in the manual scale (thanks to @DaveRGP for pointing this out):在某些情况下,需要通过命名手动比例中的值来明确级别和颜色之间的映射(感谢@DaveRGP指出这一点):

ggplot(data = datos, aes(x = fecha)) +
  geom_line(aes(y = TempMax, colour = "TempMax")) +
  geom_line(aes(y = TempMedia, colour = "TempMedia")) +
  geom_line(aes(y = TempMin, colour = "TempMin")) +
  scale_colour_manual("", 
                      values = c("TempMedia"="green", "TempMax"="red", 
                                 "TempMin"="blue")) +
  xlab(" ") +
  scale_y_continuous("Temperatura (C)", limits = c(-10,40)) + 
  labs(title="TITULO")

(giving the same figure as before). (给出与以前相同的数字)。 With named values, the breaks can be used to set the order in the legend and any order can be used in the values.使用命名值,可以使用中断来设置图例中的顺序,并且可以在值中使用任何顺序。

ggplot(data = datos, aes(x = fecha)) +
  geom_line(aes(y = TempMax, colour = "TempMax")) +
  geom_line(aes(y = TempMedia, colour = "TempMedia")) +
  geom_line(aes(y = TempMin, colour = "TempMin")) +
  scale_colour_manual("", 
                      breaks = c("TempMedia", "TempMax", "TempMin"),
                      values = c("TempMedia"="green", "TempMax"="red", 
                                 "TempMin"="blue")) +
  xlab(" ") +
  scale_y_continuous("Temperatura (C)", limits = c(-10,40)) + 
  labs(title="TITULO")

I tend to find that if I'm specifying individual colours in multiple geom's, I'm doing it wrong.我倾向于发现,如果我在多个几何图形中指定单个颜色,我做错了。 Here's how I would plot your data:以下是我将如何绘制您的数据:

##Subset the necessary columns
dd_sub = datos[,c(20, 2,3,5)]
##Then rearrange your data frame
library(reshape2)
dd = melt(dd_sub, id=c("fecha"))

All that's left is a simple ggplot command:剩下的就是一个简单的 ggplot 命令:

ggplot(dd) + geom_line(aes(x=fecha, y=value, colour=variable)) +
  scale_colour_manual(values=c("red","green","blue"))

Example plot示例图

在此处输入图像描述

I really like the solution proposed by @Brian Diggs.我真的很喜欢@Brian Diggs 提出的解决方案。 However, in my case, I create the line plots in a loop rather than giving them explicitly because I do not know apriori how many plots I will have.但是,在我的情况下,我在循环中创建线图而不是明确给出它们,因为我不知道先验我将拥有多少地块。 When I tried to adapt the @Brian's code I faced some problems with handling the colors correctly.当我尝试调整@Brian 的代码时,我在正确处理颜色方面遇到了一些问题。 Turned out I needed to modify the aesthetic functions.原来我需要修改美学功能。 In case someone has the same problem, here is the code that worked for me.如果有人遇到同样的问题,这里是对我有用的代码。

I used the same data frame as @Brian:我使用了与@Brian 相同的数据框:

data <- structure(list(month = structure(c(1317452400, 1317538800, 1317625200, 1317711600, 
                                       1317798000, 1317884400, 1317970800, 1318057200, 
                                       1318143600, 1318230000, 1318316400, 1318402800, 
                                       1318489200, 1318575600, 1318662000, 1318748400, 
                                       1318834800, 1318921200, 1319007600, 1319094000), 
                                     class = c("POSIXct", "POSIXt"), tzone = ""),
                   TempMax = c(26.58, 27.78, 27.9, 27.44, 30.9, 30.44, 27.57, 25.71, 
                               25.98, 26.84, 33.58, 30.7, 31.3, 27.18, 26.58, 26.18, 
                               25.19, 24.19, 27.65, 23.92), 
                   TempMed = c(22.88, 22.87, 22.41, 21.63, 22.43, 22.29, 21.89, 20.52,
                                 19.71, 20.73, 23.51, 23.13, 22.95, 21.95, 21.91, 20.72, 
                                 20.45, 19.42, 19.97, 19.61), 
                   TempMin = c(19.34, 19.14, 18.34, 17.49, 16.75, 16.75, 16.88, 16.82, 
                               14.82, 16.01, 16.88, 17.55, 16.75, 17.22, 19.01, 16.95, 
                               17.55, 15.21, 14.22, 16.42)), 
              .Names = c("month", "TempMax", "TempMed", "TempMin"), 
              row.names = c(NA, 20L), class = "data.frame")  

In my case, I generate my.cols and my.names dynamically, but I don't want to make things unnecessarily complicated so I give them explicitly here.就我而言,我动态生成my.colsmy.names ,但我不想让事情变得不必要的复杂,所以我在这里明确地给出它们。 These three lines make the ordering of the legend and assigning colors easier.这三行使图例的排序和颜色分配更容易。

my.cols <- heat.colors(3, alpha=1)
my.names <- c("TempMin", "TempMed", "TempMax")
names(my.cols) <- my.names

And here is the plot:这是情节:

p <-  ggplot(data, aes(x = month))

for (i in 1:3){
  p <- p + geom_line(aes_(y = as.name(names(data[i+1])), colour = 
colnames(data[i+1])))#as.character(my.names[i])))
}
p + scale_colour_manual("", 
                        breaks = as.character(my.names),
                        values = my.cols)
p

在此处输入图像描述

Another option using scale_color_identity .使用scale_color_identity的另一种选择。 The key is to specify the color name in each aes of each geom_line .关键是在每个geom_line的每个aes中指定颜色名称。 In the scale_color_identity you can mention each color as breaks and add the labels you want.scale_color_identity ,您可以提及每种颜色作为breaks并添加所需的labels Here is a reproducible example:这是一个可重现的例子:

library(ggplot2)    

temp = ggplot(data = datos, aes(x = fecha)) +
  geom_line(aes(y = TempMax, colour = "red")) +
  geom_line(aes(y = TempMedia, colour = "green")) +
  geom_line(aes(y = TempMin, colour = "blue")) +
  labs(title="TITULO") +
  ylab("Temperatura (C)") + 
  xlab(" ") + 
  scale_y_continuous(limits = c(-10,40)) + 
  scale_color_identity(name = '',
                       breaks = c('red', 'green', 'blue'),
                       labels = c("TempMax", "TempMedia", "TempMin"),
                       guide = 'legend')

temp

Created on 2022-11-19 with reprex v2.0.2创建于 2022-11-19,使用reprex v2.0.2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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