多行,每行都基于 ggplot2 中的不同数据框 - 自动着色和图例

Posted

技术标签:

【中文标题】多行,每行都基于 ggplot2 中的不同数据框 - 自动着色和图例【英文标题】:multiple lines each based on a different dataframe in ggplot2 - automatic coloring and legend 【发布时间】:2011-09-25 10:25:14 【问题描述】:

假设我有以下数据框:

df1 = data.frame(c11 = c(1:5), c12 = c(1:5))
df2 = data.frame(c21 = c(1:5), c22 = (c(1:5))^0.5)
df3 = data.frame(c31 = c(1:5), c32 = (c(1:5))^2)

我想在同一个绘图/面板中将它们绘制为线条。我可以这样做

p <- ggplot() + geom_line(data=df1, aes(x=c11, y = c12)) + 
     geom_line(data=df2, aes(x=c21,y=c22)) + 
     geom_line(data=df3, aes(x=c31, c32))

所有这些都是黑色的。如果我希望它们具有不同的颜色,我可以将颜色明确指定为geom_line() 的参数。我的问题是我可以指定几种颜色的列表,比如 5 种颜色,例如红色、蓝色、绿色、橙色、灰色,并使用该列表,这样我就不必明确指定颜色作为 geom_line 的参数() 在每一行的情况下。如果绘图 p 包含 2 个 geom_line() 语句,那么它将分别将它们着色为红色和蓝色。如果它包含 3 个 geom_line 语句,它会将它们着色为红色、蓝色和绿色。最后,如何为这些图指定图例。即使我可以在p 的末尾将颜色作为矢量提供,那也很棒。如果问题不清楚,请告诉我。

谢谢。

【问题讨论】:

【参考方案1】:

如果您使用包含不同列以指定不同美学的熔化 data.frame,则 ggplot2 效果最佳。使用常见的列名更容易融化,所以我会从那里开始。以下是我将采取的步骤:

重命名列 融化数据,添加新变量,我们将映射到颜色美学 定义您的颜色矢量 使用 scale_colour_manual 指定适当的比例

'

names(df1) <- c("x", "y")
names(df2) <- c("x", "y")
names(df3) <- c("x", "y")

newData <- melt(list(df1 = df1, df2 = df2, df3 = df3), id.vars = "x")

#Specify your colour vector
cols <- c("red", "blue", "green", "orange", "gray")

#Plot data and specify the manual scale
ggplot(newData, aes(x, value, colour = L1)) + 
  geom_line() +
  scale_colour_manual(values = cols)

为清晰起见进行了编辑

newData的结构:

'data.frame':   15 obs. of  4 variables:
 $ x       : int  1 2 3 4 5 1 2 3 4 5 ...
 $ variable: Factor w/ 1 level "y": 1 1 1 1 1 1 1 1 1 1 ...
 $ value   : num  1 2 3 4 5 ...
 $ L1      : chr  "df1" "df1" "df1" "df1" ...

还有剧情本身:

【讨论】:

@Chase。谢谢!但是,您给出的示例绘制了一条线,而不是三条不同的线。我想我可以通过将group = L1 作为参数添加到aes() 来解决这个问题。问题在于传说。你能试试吗?传说没有意义。图例中包含三个以上的键。 @Curious - 你的真实数据的结构是什么?运行上面的代码会产生三行带有对我来说直观的图例......我将使用newData 的 str 更新我的答案并给出我所看到的情节。除非您的数据不代表您的示例数据,否则不确定您为什么会得到其他东西。如果需要,您可以强制 L1 成为一个因素,但这不应该成为问题。 @Chase。感谢您的澄清。出于某种原因,在我的例子中,L1 变量是int(1 1 1 1 1 2 2 2 等)而不是chr。如果我纠正它,它会起作用。现在我需要弄清楚如何更改图例标题和名称。感谢您的帮助。 @Curious - 如果我没有在对melt() 的调用中给出列表对象名称,我可以复制这些结果。我给每个 data.frame 起了一个名字...df1 = df1,你可以随意命名它们...foo = df1, bar = df2, baz = df3。如果您不命名它们,那么它们只会被分配整数值。可以使用scale_colour_manual(name = "yahtzee", ...) 更改图例标题。当您融化数据时,我会将名称设置为您想要的名称。 @geotheory - 是的,这根本不是什么大问题。 ggplot2 具有用于点的特定几何形状和另一个适合您选择的数据模型的几何形状。要采用上面的数据来显示带有来自线性模型的斜线的 xy 散点图,将是 geom_point() + geom_smooth(method = "lm")。查看ggplot2 website 了解有关可用的不同几何形状的更多详细信息。【参考方案2】:

您不必融化、分组或聚集。它很简单。只需将颜色添加到 geom_line

library(tidyverse)

df1 = data.frame(c11 = c(1:5), c12 = c(1:5))
df2 = data.frame(c21 = c(1:5), c22 = (c(1:5))^0.5)
df3 = data.frame(c31 = c(1:5), c32 = (c(1:5))^2)

p <- ggplot() + geom_line(data=df1, aes(x=c11, y = c12), color= "red") + 
  geom_line(data=df2, aes(x=c21,y=c22), color = "blue") + 
  geom_line(data=df3, aes(x=c31, c32), color = "green")
p

【讨论】:

【参考方案3】:

如果您将自己的想法调整为ggplot2 处理图形的方式,这些问题就会变得更容易解决。 ggplot2 的组织理念是,图表中出现的所有内容(原则上)都应作为数据框中的一列存在。 (当然也有例外,但这是一般的想法。)

因此,您尝试逐条构建此图表,一次一条,每条来自不同的数据帧,然后然后为它们分配颜色非常不符合ggplot2ish。如果您想用不同颜色标记图表中的事物,您的第一个想法应该始终是:

如何将此颜色标签信息编码为变量

在这种情况下,解决方案相当简单。只需将您的三个数据框 rbind 放在一起(您需要先确保列名匹配)并创建一个新列,例如 grp,该列具有与您的三个数据框相对应的三个级别:

dat <- rbind(df1,df2,df3)
dat$grp <- rep(factor(1:3),times = c(nrow(df1),nrow(df2),nrow(df3)))

然后 map变量 grp 映射到 ggplot 调用中的 aesthetic 颜色:

ggplot(data = dat, aes(x=...,y=...,colour = grp) + 
    geom_line()

最后,如果您不喜欢默认颜色,可以使用scale_colour_manual 指定自己的颜色:

+ scale_colour_manual(value = c('green','blue','grey'))

或者您可以使用来自scale_colour_brewer 的一些不错的“预选”调色板。

编辑:我修正了上面的错字以确保grp 是一个因素。这是我的最终版本:

df1 = data.frame(c1 = c(1:5), c2 = c(1:5))
df2 = data.frame(c1 = c(1:5), c2 = (c(1:5))^0.5)
df3 = data.frame(c1 = c(1:5), c2 = (c(1:5))^2)

dat <- rbind(df1,df2,df3)
dat$grp <- rep(factor(1:3),times=c(nrow(df1),nrow(df2),nrow(df3)))

ggplot(data = dat, aes(x = c1, y = c2, colour = grp)) + 
    geom_line()

【讨论】:

以上是关于多行,每行都基于 ggplot2 中的不同数据框 - 自动着色和图例的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据库中的多行显示到多个文本框?

如何基于一个列对象删除熊猫数据框中的多行? [复制]

基于非数字第三变量的热图轴重新排序 - ggplot2

向表中插入多行 - Access

从文件中读取多行中的多个值(Java)

如何将图例添加到 ggplot2 中的多行?