使用不同的美学元素在ggplot直方图中添加图例

3
我想在我的一个图表中添加一个图例,但是我有不同的美学和我从未创建过图例,所以我觉得很难确定如何构建它。
我的一个美学是填充代码,我手动添加了一个向量。另一个美学是我用geom_vline添加的垂直线。
从下面的图表中,有三个特征我想要添加到图例中:1)深蓝色的条形,2)浅蓝色的条形和3)垂直线。
有没有人对如何高效编写代码有建议?
#df
df <- data.frame(Time_Diff <- runif(1000, 0, 200))


# Show median, IQR range and outliers
colors <- c(rep("blue",3), rep("paleturquoise2",38))
bp_overall <- ggplot(data = df, aes(Time_Diff)) 
bp_overall + 
  geom_histogram(binwidth = 5, fill = colors) + #create histogram
  ggtitle("Time Difference")  +
  xlab("Time in Days") +
  ylab("Amount") +
  geom_vline(xintercept = 3, linetype = "twodash", size = 1,      colour= "darkblue") + #show median
  scale_x_continuous(breaks = seq(0, 202, 10)) +
  theme_light() +
  theme(panel.grid.minor = element_blank(),
    panel.border = element_blank(), #remove all border lines
    axis.line.x = element_line(size = 0.5, linetype = "solid", colour = "black"), #add x-axis border line
    axis.line.y = element_line(size = 0.5, linetype = "solid", colour = "black")) + #add y-axis border line
  theme(plot.title = element_text(family = windowsFont("Verdana"),     color="black", size=14, hjust = 0.5)) +
  theme(axis.title = element_text(family = windowsFont("Verdana"), color="black", size=12)) 

在Djork的建议下,我编写了下面的脚本,它可以正常工作,我很满意。现在唯一想要实现的是让图例成为一个整体(直方图图例和折线图图例合并成一个连贯整体)。是否有任何建议?

# reformat data
set.seed(1)
df <- data.frame(runif(1000, 0, 200))
colnames(df) <- "Time_Diff"

bp_overall + 
  geom_histogram(data = subset(df, Time_Diff <= 12.5), aes(x = Time_Diff, fill="BAR BLUE"), binwidth = 5) + # subset for blue data, where aes fill is fill group 1 label
  geom_histogram(data = subset(df, Time_Diff > 12.5), aes(x = Time_Diff, fill="BAR TURQUOISE"), binwidth = 5) + # subset for turquoise data, where aes fill is fill group 2 label
  scale_fill_manual("Histogram Legend", values=c("blue", "paleturquoise2")) + # manually assign histogram fill colors
  geom_vline(aes(xintercept = 3, colour="LINE DARK BLUE"), linetype="twodash", size = 1) + # where aes colour is vline label
  scale_colour_manual("Line Legend", values="darkblue") + #removed legend title
  scale_x_continuous(breaks = seq(0, 202, 10)) +
  ggtitle("Time Difference")  +
  xlab("Time in Days") +
  ylab("Amount") +
  theme_light() +
  theme(panel.grid.minor = element_blank(),
        panel.border = element_blank(), 
        axis.line.x = element_line(size = 0.5, linetype = "solid", colour = "black"), 
        axis.line.y = element_line(size = 0.5, linetype = "solid", colour = "black"),
        legend.position = c(0.95, 0.95),
        legend.justification = c("right", "top"),
        legend.box.just = ("right"))

获取图例的最简单方法是在 aes() 内指定特征。因此,您需要转换包括统计数据和颜色列的数据框架。请参见 这里这里 - Roman
@Jimbou 我想我理解了你所说的转换数据框的意思。我已经在我的问题中做过这个(请参见下面的解决方案概念代码),但我无法弄清楚如何调整我的 ggplot 图中的代码。 - SHW
1个回答

6

我认为@Jimbou的建议更好,但是有一种通过将字符值分配给geom_histogram aes fill 值和geom_vline aes colour 值来人工创建图例的方法,然后在scale_fill_manual 或者scale_colour_manual 中设置颜色。

然而,使用这种方法时,aes fill 只能取一个值(长度为1),因此您必须对蓝色和青色的值进行子集划分,并为每个值绘制直方图,其中截止点由您的binwidth 确定。

以下是该方法。请注意,您的数据需要重新格式化。

# reformat data
set.seed(1)
df <- data.frame(runif(1000, 0, 200))
colnames(df) <- "Time_Diff"


bp_overall <- ggplot(data = df) 
bp_overall +
  geom_histogram(data = subset(df, Time_Diff <= 12.5), aes(x = Time_Diff, fill="BAR BLUE"), binwidth = 5) + # subset for blue data, where aes fill is fill group 1 label
  geom_histogram(data = subset(df, Time_Diff > 12.5), aes(x = Time_Diff, fill="BAR TURQUOISE"), binwidth = 5) + # subset for turquoise data, where aes fill is fill group 2 label
  scale_fill_manual("Histogram Legend", values=c("blue", "paleturquoise2")) + # manually assign histogram fill colors
  geom_vline(aes(xintercept = 3, colour="LINE DARK BLUE"), linetype="twodash", size = 1) + # where aes colour is vline label
  scale_colour_manual("Line Legend", values="darkblue") + # manually assign vline colors
  scale_x_continuous(breaks = seq(0, 202, 10)) +
  ggtitle("Time Difference")  +
  xlab("Time in Days") +
  ylab("Amount") +
  theme_light() +
  theme(panel.grid.minor = element_blank(),
    panel.border = element_blank(), 
    axis.line.x = element_line(size = 0.5, linetype = "solid", colour = "black"), 
    axis.line.y = element_line(size = 0.5, linetype = "solid", colour = "black"))

等等,添加您剩下的 主题

在此输入图片描述

编辑:回答如何统一图例并减少两种图例类型之间的间距

(1) 通过在 scale_fill_manual 中将 vline 的图例名称设置为 "" 来删除图例名称,将直方图填充图例的 名称 更改为 "Legend" 在 scale_colour_manual 中。

(2) 指定图例出现的 顺序,先使用 guides guide_legend 填充,然后再进行颜色。

(3) 使用 legend.spacing.y 将两种图例类型之间的 y-间距设置为 0,并使用 theme 中的 legend.margin 删除顶部和底部的边距。

bp_overall <- ggplot(data = df) 
bp_overall +
  geom_histogram(data = subset(df, Time_Diff <= 12.5), aes(x = Time_Diff, fill="BAR BLUE"), binwidth = 5) + 
  geom_histogram(data = subset(df, Time_Diff > 12.5), aes(x = Time_Diff, fill="BAR TURQUOISE"), binwidth = 5) + 
  scale_fill_manual(name="Legend", values=c("blue", "paleturquoise2")) +
  geom_vline(aes(xintercept = 3, colour="LINE DARK BLUE"), linetype="twodash", size = 1) + 
  scale_colour_manual(name="", values="darkblue") + 
  scale_x_continuous(breaks = seq(0, 202, 10)) +
  ggtitle("Time Difference")  +
  xlab("Time in Days") +
  ylab("Amount") +
  theme_light() +
  theme(panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    axis.line.x = element_line(size = 0.5, linetype = "solid", colour = "black"),
    axis.line.y = element_line(size = 0.5, linetype = "solid", colour = "black"),
    legend.spacing.y = unit(0, "cm"),
    legend.margin=margin(t=0, r=0.5, b=0, l=0.5, unit="cm")) +
  guides(fill = guide_legend(order = 1), 
     colour = guide_legend(order = 2))

enter image description here


感谢您的建议。因为您和Jimdou都指出了一种更简洁的方法来完成这个任务。我添加了一小段代码来转换数据框,使其适合在ggplot中使用,但我不知道该怎么继续下去。您能否检查一下我的问题中的新代码? - SHW
我试图将我的代码转换成你的,但是我遇到了以下错误:'Error: Aesthetics must be either length 1 or the same as the data (77): x, fill, binwidth'。你所说的重新整理df是什么意思? - SHW
您需要提供数据或子集以重现错误,以便我们进行故障排除。但很可能是您给出的aes长度超过了我上面使用的1个字符。 - Djork
抱歉,还有一个问题:)。只有一个图例(而不是单独的直方图图例和线图例)将是完美的。通过在scale_color_manual代码行中删除“Line Legend”文本(将其替换为“”),我离这个目标又近了一步。但是,线条的图例仍然比其他图例指示远得多。你知道有没有办法让“LINE DARK BLUE”变量成为“直方图图例”的一员吗?(至少在视觉上) - SHW
请查看有关统一图例的解决方法的编辑后答案。如果这对您有用,请接受答案以标记为已解决。 - Djork
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接