首页 > 解决方案 > 自定义 ggplot 图例

问题描述

假设我有一些数据并想使用 ggplot 绘制预测和 95% 的预测区间。以下代码有效并给出了可接受的图例。

ExampleData = data.frame(t = 1:10, f = rep(1,10), Lower = rep(0.5, 10), Upper = rep(1.5, 10))
library (ggplot2)
ggplot(data = ExampleData)+
  geom_point(aes(x=t, y =f, colour = "Forecasts"))+
  geom_point(aes(x=t, y =Lower), shape=95)+
  geom_segment(aes(x=t, y = Lower, xend=t, yend = f))+
  geom_point(aes(x=t, y =Upper), shape=95)+
  geom_segment(aes(x=t, y = f, xend=t, yend = Upper))+
  geom_vline(aes(xintercept = 11, colour = "95% PI"))+
  scale_colour_manual(values = c("95% PI" = "black","Forecasts" = "red"),
                      guide = guide_legend(override.aes = list(
                        linetype = c('solid','blank'),
                        shape = c(NA,16))))+
  scale_x_continuous(name="Time", limits=c(1, 10), breaks = c(0,5,10))+
  labs(title="Example")+
  labs(y = "Forecasts")+
  theme_bw()

示例的 rplot

我还想添加一条水平线,例如y = 0.75. 但是,图例似乎无法容纳水平和垂直线。有没有办法可以使用 ggplot 来做到这一点?还包括较短的水平线怎么样?例如,上点和下点由短水平线表示。

标签: rggplot2

解决方案


更新考虑到OP的评论:

如果定义了美学color, fill, group, ... ,则该元素会自动添加到图例中。因此,类似的东西geom_line(aes(color = 'foo'))会产生一个名为foo的图例元素,但geom_line(color = 'black')不会。

library (ggplot2)
ExampleData = data.frame(t = 1:10, f = 1, Lower = 0.5, Upper = 1.5)

g <- ggplot(data = ExampleData, aes(x = t))

g <- g + geom_point(aes(y = f, color = "95% PI"), size = 0)
g <- g + geom_errorbar(aes(ymin = Lower, ymax = Upper, color = "95% PI"))
g <- g + geom_point(aes(y = f), color = "red")
g <- g + geom_line(aes(y = 0.75, color = "Threshold"))

g <- g + scale_colour_manual(values = c("95% PI"    = "black",
                                        "Threshold" = "green"),
                             guide = guide_legend(override.aes = list(
                               linetype = c('blank', 'solid'),
                               shape    = c('|',      NA),
                               size     = c(5,        0.5))))

g <- g + theme_bw()
g <- g + scale_x_continuous(name="Time", breaks = c(0, 5, 10))
g <- g + labs(title = "Example")
g <- g + labs(y = "Forecasts")

print(g)

这将产生如下输出: 上述RPlot的结果

为了得到图例中的垂直线,我添加了一个不可见的geom_point(大小为 0,原因见下文)。请注意,color美学已定义,因此图例将由该元素填充。要在固定y值和图例中添加水平线,最简单的方法是使用geom_line元素设置color美学。最后,要显示红点并将其从图例中排除,您不得设置color美学。

g <- g + geom_point(aes(y = f, color = "95% PI"), size = 0)
g <- g + geom_errorbar(aes(ymin = Lower, ymax = Upper, color = "95% PI"))
g <- g + geom_line(aes(y = 0.75, color = "Threshold"))
g <- g + geom_point(aes(y = f), color = "red")

关于图例,要使用垂直条而不是水平条(默认),您可以使用 shape |。默认情况下这是一个相当小的形状(至少在我的计算机上),因此您可能需要稍微增加它的大小。您可以通过使用指南来做到这一点。注意geom_errorbar还是geom_segment没有属性。_ shape要使用形状而不是线条,您需要先添加不可见的geom_point

g <- g + scale_colour_manual(values = c("95% PI"    = "black",
                                        "Threshold" = "green"),
                             guide = guide_legend(override.aes = list(
                               linetype = c('blank', 'solid'),
                               shape    = c('|',      NA),
                               size     = c(5,        0.5))))

上一个答案:

假设您想要图例中的点、垂直线段、水平线段和水平线,这是我的建议:

ExampleData = data.frame(t = 1:10, f = rep(1,10), Lower = rep(0.5, 10), Upper = rep(1.5, 10))
library (ggplot2)

tipw <- 0.2
g <- ggplot(data = ExampleData)

g <- g + geom_segment(aes(x = t, y = Lower, xend = t, yend = Upper, color = "95% PI"))
g <- g + geom_segment(aes(x = t - tipw / 2, y = Lower, xend = t + tipw / 2, yend = Lower, color = "Minimum"))
g <- g + geom_segment(aes(x = t - tipw / 2, y = Upper, xend = t + tipw / 2, yend = Upper, color = "Maximum"))
g <- g + geom_point(aes(x = t, y = f, color = "Forecasts"))
g <- g + geom_line(aes(x = t, y = 0.75, color = "Some value"))

g <- g + scale_x_continuous(name="Time", limits=c(1 - tipw/2, 10 + tipw/2), breaks = c(0, 5, 10))
g <- g + labs(title = "Example")
g <- g + labs(y = "Forecasts")

g <- g + scale_colour_manual(values = c("95% PI"     = "black",
                                        "Forecasts"  = "red",
                                        "Minimum"    = "orange",
                                        "Maximum"    = "green",
                                        "Some value" = "light blue"),
                             guide = guide_legend(override.aes = list(
                                     linetype = c('solid', 'blank', 'solid', 'solid', 'solid'),
                                     shape    = c(NA,      16,      NA,      NA,      NA))))
g <- g + theme_bw()

print(g)

示例的 Rplot

tipw <- 0.2
g <- ggplot(data = ExampleData)

使用您的数据创建绘图。变量是尖端的宽度(使用与x 轴tipw相同的单位)。见下文。

g <- g + geom_segment(aes(x = t, y = Lower, xend = t, yend = Upper, color = "95% PI"))
g <- g + geom_segment(aes(x = t - tipw / 2, y = Lower, xend = t + tipw / 2, yend = Lower, color = "Minimum"))
g <- g + geom_segment(aes(x = t - tipw / 2, y = Upper, xend = t + tipw / 2, yend = Upper, color = "Maximum"))
g <- g + geom_point(aes(x = t, y = f, color = "Forecasts"))
g <- g + geom_line(aes(x = t, y = 0.75, color = "Some value"))

添加直线、线段和点。元素将按照您编写它们的顺序堆叠。所以这里将首先绘制尖端的短水平条,然后是垂直条,然后是条顶部的点,然后是其余部分顶部的任意水平线。

请记住,您可以在 ggplot 的美学中做一些逻辑。短水平条在此定义为从 开始到x = t - tipw / 2结束的段x = t + tipw / 2。长水平条可以手动定义为y = 0.75。这是有效的,因为您始终可以使用长度为 1 的向量进行美学处理,并且该值将用于所有点(aes(x = t, y = 0.75)给出与 相同的结果aes(x = t, y = rep(0.75, length(t))))。

g <- g + scale_x_continuous(name = "Time", limits=c(1 - tipw/2, 10 + tipw/2), breaks = c(0, 5, 10))

您必须包括水平线段的xstartxend才能绘制它们。这就是限制扩展的原因tipw/2。否则最左边和最右边的水平条将不可见,并会抛出警告。

Warning messages:
1: Removed 2 rows containing missing values (geom_segment). 
2: Removed 2 rows containing missing values (geom_segment). 

推荐阅读