如何为这个 ggplot2 脚本定义和添加图例?
How can I define and add a lagend to this ggplot 2 script?
我想出了以下脚本来对 X 值上的数据进行分箱,并在重叠条形图中绘制这些分箱的均值。它工作正常,但我似乎无法生成图例,可能是由于对美学映射的理解不足。
这里是脚本,注意“MOI”和“T_cell_contacts”是每个DF中的两个数据列。
ggplot(mapping=aes(MOI, T_cell_contacts)) + stat_summary_bin(data = Cleaned24hr4, fun = "mean", geom="bar", bins= 100, fill = "#FF6666", alpha = 0.3) + stat_summary_bin(data = cleaned24hr8, fun = "mean", geom="bar", bins= 100, fill = "#3733FF", alpha = 0.3) + ylab("mean")
我还添加了它绘制的图表。
我认为困难在于用两个不同的 geom 构建一个图例。我的方法是将您的数据合并到一个数据框中。每个记录都被一个新的类别列分开,我将简称为“猫”。
使用流行的 dplyr 包:
Cleaned24hr4 <- mutate(Cleaned24hr4, cat = "hr4")
Cleaned24hr8 <- mutate(Cleaned24hr8, cat = "hr8")
然后把它们放在一起:
Cleaned <- union(Cleaned24hr4,Cleaned24hr8)
定义你的颜色:
colorcode <- c("hr4" = "#FF6666", "hr8" = "#3733FF")
这是我的 ggplot 语句:
ggplot(Cleaned, mapping=aes(MOI, T_cell_contacts)) +
stat_summary_bin(fun = "mean", geom="bar", bins= 100, aes(fill = cat), alpha = 0.3) +
scale_fill_manual(values = colorcode) +
ylab("mean")
使用一些虚拟数据输出。
完全披露:当@schumacher 发布他们的回复时,我正在写这篇文章:)。无论如何决定完成。
有两种方法可以解决这个问题。一种方法(更复杂)是将数据帧分开并要求 ggplot2
通过映射创建图例,第二种(更简单)方法是合并成一个类似于@schumacher 发布的数据集并映射填充颜色到创建的额外 id 列。
我会向你们展示,但首先,这是一个示例数据集:
library(ggplot2)
set.seed(8675309)
df1 <- data.frame(my_x=rep(1:100, 3), my_y=rnorm(300, 40, 4))
df2 <- data.frame(my_x=rep(11:110, 3), my_y=rnorm(300, 110, 10))
# and the plot code similar to OP's question
ggplot(mapping=aes(x = my_x, y = my_y)) +
stat_summary_bin(data=df1, fun="mean", geom="bar", bins=40, fill="blue", alpha=0.3) +
stat_summary_bin(data=df2, fun="mean", geom="bar", bins=40, fill="red", alpha=0.3)
方法 1:合并数据帧
这是首选 方法,由于多种原因我无法在此一一列举。您可以使用很多选项来组合数据集。一种是在向数据添加某种 ID 列后使用 union()
或 rbind()
,但您可以使用 dplyr
:[=52= 中的 bind_rows()
一次完成所有操作]
df <- dplyr::bind_rows(list(dataset1 = df1, dataset2 = df2), .id="id")
结果会将行绑定在一起并通过指定 .id
参数,它将在名为 "id"
的数据集中创建一个新列,该列使用列表中每个数据集的名称作为价值。在这种情况下,thd df$id
列中的值是 "dataset1"
如果它源自 df1
或 "dataset2"
如果它源自 df2
.
然后使用 aes(fill=...)
将填充颜色映射到组合数据集中的列 "id"
。
p <- ggplot(df, aes(x=my_x, y=my_y)) +
stat_summary_bin(aes(fill=id), fun="mean", geom="bar", bins=40, alpha=0.3)
p
这将使用 fill
的默认颜色创建绘图,因此如果您想提供自己的颜色,只需使用 scale_fill_manual(values=...)
指定特定颜色即可。为 values=
使用命名向量可确保按您希望的方式应用每种颜色,但您可以只提供一个未命名的颜色名称向量。
p + scale_fill_manual(values = c("dataset1" = "blue", "dataset2" = "red"))
方法二:使用映射添加图例
虽然首选方法 1,但还有另一种方法不会强制您合并数据帧。这也有助于说明 ggplot2
如何决定创建和绘制图例。图例是通过 mapping=
参数自动创建的,特别是通过 aes()
。如果你在 aes()
中放置任何通常会赋予不同外观而不是位置的美学(除了一些例外,如 x
、y
和 label
),那么这会启动创造一个传奇。您可以映射 数据集中的一列(如上), 或 您可以只提供一个值,该值将应用于整个用于 geom 的数据集。在这种情况下,当您将每个 geom 调用的 fill=
参数更改为 aes()
内并将其分配给一个字符值时,看看会发生什么:
p1 <- ggplot(mapping = aes(x=my_x, y=my_y)) +
stat_summary_bin(aes(fill="first"), data=df1, fun="mean", geom="bar", bins=40, alpha=0.3) +
stat_summary_bin(aes(fill="second"), data=df2, fun="mean", geom="bar", bins=40, alpha=0.3) +
scale_fill_manual(values = c("first" = "blue", "second" = "red"))
p1
有效!当您为 aes()
内的 fill=
审美提供一个字符值时,它基本上是将该数据中的每个观察标记为具有值 "first"
或 "second"
并使用它来制作传奇。很酷吧?
您注意到一个问题,即图例的 alpha 值不正确。这是因为你 overplotting。这只是您不应该真正这样做的原因之一,但是……有点管用。仅当您具有 alpha 值时才会注意到。你可以让它看起来很正常,但你需要使用 guide_legend()
来覆盖美学。由于代码有效地导致为每个几何体完全绘制图例...您必须将 alpha 值减半才能正确显示。
p1 + guides(fill=guide_legend(override.aes = list(alpha=0.15)))
哦,不使用方法 2 的真正原因是......想想对 5 个数据集再做一次......10 个怎么样?......20 个怎么样?......
我想出了以下脚本来对 X 值上的数据进行分箱,并在重叠条形图中绘制这些分箱的均值。它工作正常,但我似乎无法生成图例,可能是由于对美学映射的理解不足。
这里是脚本,注意“MOI”和“T_cell_contacts”是每个DF中的两个数据列。
ggplot(mapping=aes(MOI, T_cell_contacts)) + stat_summary_bin(data = Cleaned24hr4, fun = "mean", geom="bar", bins= 100, fill = "#FF6666", alpha = 0.3) + stat_summary_bin(data = cleaned24hr8, fun = "mean", geom="bar", bins= 100, fill = "#3733FF", alpha = 0.3) + ylab("mean")
我还添加了它绘制的图表。
我认为困难在于用两个不同的 geom 构建一个图例。我的方法是将您的数据合并到一个数据框中。每个记录都被一个新的类别列分开,我将简称为“猫”。 使用流行的 dplyr 包:
Cleaned24hr4 <- mutate(Cleaned24hr4, cat = "hr4")
Cleaned24hr8 <- mutate(Cleaned24hr8, cat = "hr8")
然后把它们放在一起:
Cleaned <- union(Cleaned24hr4,Cleaned24hr8)
定义你的颜色:
colorcode <- c("hr4" = "#FF6666", "hr8" = "#3733FF")
这是我的 ggplot 语句:
ggplot(Cleaned, mapping=aes(MOI, T_cell_contacts)) +
stat_summary_bin(fun = "mean", geom="bar", bins= 100, aes(fill = cat), alpha = 0.3) +
scale_fill_manual(values = colorcode) +
ylab("mean")
使用一些虚拟数据输出。
完全披露:当@schumacher 发布他们的回复时,我正在写这篇文章:)。无论如何决定完成。
有两种方法可以解决这个问题。一种方法(更复杂)是将数据帧分开并要求 ggplot2
通过映射创建图例,第二种(更简单)方法是合并成一个类似于@schumacher 发布的数据集并映射填充颜色到创建的额外 id 列。
我会向你们展示,但首先,这是一个示例数据集:
library(ggplot2)
set.seed(8675309)
df1 <- data.frame(my_x=rep(1:100, 3), my_y=rnorm(300, 40, 4))
df2 <- data.frame(my_x=rep(11:110, 3), my_y=rnorm(300, 110, 10))
# and the plot code similar to OP's question
ggplot(mapping=aes(x = my_x, y = my_y)) +
stat_summary_bin(data=df1, fun="mean", geom="bar", bins=40, fill="blue", alpha=0.3) +
stat_summary_bin(data=df2, fun="mean", geom="bar", bins=40, fill="red", alpha=0.3)
方法 1:合并数据帧
这是首选 方法,由于多种原因我无法在此一一列举。您可以使用很多选项来组合数据集。一种是在向数据添加某种 ID 列后使用 union()
或 rbind()
,但您可以使用 dplyr
:[=52= 中的 bind_rows()
一次完成所有操作]
df <- dplyr::bind_rows(list(dataset1 = df1, dataset2 = df2), .id="id")
结果会将行绑定在一起并通过指定 .id
参数,它将在名为 "id"
的数据集中创建一个新列,该列使用列表中每个数据集的名称作为价值。在这种情况下,thd df$id
列中的值是 "dataset1"
如果它源自 df1
或 "dataset2"
如果它源自 df2
.
然后使用 aes(fill=...)
将填充颜色映射到组合数据集中的列 "id"
。
p <- ggplot(df, aes(x=my_x, y=my_y)) +
stat_summary_bin(aes(fill=id), fun="mean", geom="bar", bins=40, alpha=0.3)
p
这将使用 fill
的默认颜色创建绘图,因此如果您想提供自己的颜色,只需使用 scale_fill_manual(values=...)
指定特定颜色即可。为 values=
使用命名向量可确保按您希望的方式应用每种颜色,但您可以只提供一个未命名的颜色名称向量。
p + scale_fill_manual(values = c("dataset1" = "blue", "dataset2" = "red"))
方法二:使用映射添加图例
虽然首选方法 1,但还有另一种方法不会强制您合并数据帧。这也有助于说明 ggplot2
如何决定创建和绘制图例。图例是通过 mapping=
参数自动创建的,特别是通过 aes()
。如果你在 aes()
中放置任何通常会赋予不同外观而不是位置的美学(除了一些例外,如 x
、y
和 label
),那么这会启动创造一个传奇。您可以映射 数据集中的一列(如上), 或 您可以只提供一个值,该值将应用于整个用于 geom 的数据集。在这种情况下,当您将每个 geom 调用的 fill=
参数更改为 aes()
内并将其分配给一个字符值时,看看会发生什么:
p1 <- ggplot(mapping = aes(x=my_x, y=my_y)) +
stat_summary_bin(aes(fill="first"), data=df1, fun="mean", geom="bar", bins=40, alpha=0.3) +
stat_summary_bin(aes(fill="second"), data=df2, fun="mean", geom="bar", bins=40, alpha=0.3) +
scale_fill_manual(values = c("first" = "blue", "second" = "red"))
p1
有效!当您为 aes()
内的 fill=
审美提供一个字符值时,它基本上是将该数据中的每个观察标记为具有值 "first"
或 "second"
并使用它来制作传奇。很酷吧?
您注意到一个问题,即图例的 alpha 值不正确。这是因为你 overplotting。这只是您不应该真正这样做的原因之一,但是……有点管用。仅当您具有 alpha 值时才会注意到。你可以让它看起来很正常,但你需要使用 guide_legend()
来覆盖美学。由于代码有效地导致为每个几何体完全绘制图例...您必须将 alpha 值减半才能正确显示。
p1 + guides(fill=guide_legend(override.aes = list(alpha=0.15)))
哦,不使用方法 2 的真正原因是......想想对 5 个数据集再做一次......10 个怎么样?......20 个怎么样?......