如何用 "jitter" 生成相同的图,以及如何抖动选定的点(不是所有点)?
How to generate the same plot with "jitter", and how to jitter selected points (not all points)?
我想做的是:
a) 让 ggplot
代码生成的情节每次都相同 运行s [set.seed 种概念?]和
b) 仅对具有相同 y 轴值的标签抖动文本标签——让其他文本标签保持不变。这似乎是某种基于点的因子值的条件抖动。
这是一些数据:
dput(df)
structure(list(Firm = c("a verylongname", "b verylongname", "c verylongname",
"d verylongname", "e verylongname", "f verylongname", "g verylongname",
"h verylongname", "i verylongname", "j verylongname"), Sum = c(74,
77, 79, 82, 85, 85, 88, 90, 90, 92)), .Names = c("Firm", "Sum"
), row.names = c(NA, 10L), class = "data.frame")
这是使用 df 的 ggplot
代码:
ggplot(df, aes(x = reorder(Firm, Sum, mean), y = Sum)) +
geom_text(aes(label = Firm), size = 3, show.guides = FALSE, position = position_jitter(height = .9)) +
theme(axis.text.x = element_blank()) +
scale_x_discrete(expand = c(-1.1, 0)) + # to show the lower left name fully
labs(x = "", y = "", title = "")
注意绘图的一个版本仍然与 h 和 i 重叠——每次我 运行 上面的代码文本标签的位置都会改变。
顺便说一句,这个问题 conditional jitter 稍微移动了 x 轴上的离散值,但我想(仅)移动 y 轴上的重叠点。
一种选择是添加一列来标记重叠点,然后分别绘制它们。更好的选择可能是直接移动重叠点的 y 值,这样我们就可以直接控制它们的位置。我在下面显示了两个选项。
选项1(抖动):首先,添加一列来标记重叠。在这种情况下,因为这些点几乎落在一条线上,所以如果它们的 y 值太接近,我们可以将任何点标记为重叠。如果检查 x 值是否接近也很重要,您可以包含更复杂的条件。
df$overlap = lapply(1:nrow(df), function(i) {
if(min(abs(df[i, "Sum"] - df$Sum[-i])) <= 1) "Overlap" else "Ignore"
})
在图中,我将抖动的点涂成红色,这样很容易分辨出哪些点受到了影响。
# Add set.seed() here to make jitter reproducible
ggplot(df, aes(x = reorder(Firm, Sum, mean))) +
geom_text(data=df[df$overlap=="Overlap",],
aes(label = Firm, y = Sum), size = 3,
position = position_jitter(width=0, height = 1), colour="red") +
geom_text(data=df[df$overlap=="Ignore",],
aes(label = Firm, y = Sum), size = 3) +
theme(axis.text.x = element_blank()) +
scale_x_discrete(expand = c(-1.1, 0)) + # to show the lower left name fully
labs(x = "", y = "", title = "")
选项 2(直接放置): 另一个选项是直接控制标签的移动量,而不是采取任何 jitter
碰巧给我们的东西。在这种情况下,我们知道我们想要移动具有相同 y 值的每对点。在我们需要同时担心 x 和 y 值的情况下,需要更复杂的逻辑,在同一重叠中有两个以上的点,and/or 我们需要移动接近但不完全相同的值。
library(dplyr)
# Create a new column that shifts pairs of points with the same y-value by +/- 0.25
df = df %>% group_by(Sum) %>%
mutate(SumNoOverlap = if(n()>1) Sum + c(-0.25,0.25) else Sum)
ggplot(df, aes(x = reorder(Firm, Sum, mean), y = SumNoOverlap)) +
geom_text(aes(label = Firm), size = 3) +
theme(axis.text.x = element_blank()) +
scale_x_discrete(expand = c(-1.1, 0)) + # to show the lower left name fully
labs(x = "", y = "", title = "")
注意: 要使抖动可重现,请在抖动绘图代码前添加 set.seed(153)
(或您想要的任何种子值)。
我想做的是:
a) 让 ggplot
代码生成的情节每次都相同 运行s [set.seed 种概念?]和
b) 仅对具有相同 y 轴值的标签抖动文本标签——让其他文本标签保持不变。这似乎是某种基于点的因子值的条件抖动。
这是一些数据:
dput(df)
structure(list(Firm = c("a verylongname", "b verylongname", "c verylongname",
"d verylongname", "e verylongname", "f verylongname", "g verylongname",
"h verylongname", "i verylongname", "j verylongname"), Sum = c(74,
77, 79, 82, 85, 85, 88, 90, 90, 92)), .Names = c("Firm", "Sum"
), row.names = c(NA, 10L), class = "data.frame")
这是使用 df 的 ggplot
代码:
ggplot(df, aes(x = reorder(Firm, Sum, mean), y = Sum)) +
geom_text(aes(label = Firm), size = 3, show.guides = FALSE, position = position_jitter(height = .9)) +
theme(axis.text.x = element_blank()) +
scale_x_discrete(expand = c(-1.1, 0)) + # to show the lower left name fully
labs(x = "", y = "", title = "")
注意绘图的一个版本仍然与 h 和 i 重叠——每次我 运行 上面的代码文本标签的位置都会改变。
顺便说一句,这个问题 conditional jitter 稍微移动了 x 轴上的离散值,但我想(仅)移动 y 轴上的重叠点。
一种选择是添加一列来标记重叠点,然后分别绘制它们。更好的选择可能是直接移动重叠点的 y 值,这样我们就可以直接控制它们的位置。我在下面显示了两个选项。
选项1(抖动):首先,添加一列来标记重叠。在这种情况下,因为这些点几乎落在一条线上,所以如果它们的 y 值太接近,我们可以将任何点标记为重叠。如果检查 x 值是否接近也很重要,您可以包含更复杂的条件。
df$overlap = lapply(1:nrow(df), function(i) {
if(min(abs(df[i, "Sum"] - df$Sum[-i])) <= 1) "Overlap" else "Ignore"
})
在图中,我将抖动的点涂成红色,这样很容易分辨出哪些点受到了影响。
# Add set.seed() here to make jitter reproducible
ggplot(df, aes(x = reorder(Firm, Sum, mean))) +
geom_text(data=df[df$overlap=="Overlap",],
aes(label = Firm, y = Sum), size = 3,
position = position_jitter(width=0, height = 1), colour="red") +
geom_text(data=df[df$overlap=="Ignore",],
aes(label = Firm, y = Sum), size = 3) +
theme(axis.text.x = element_blank()) +
scale_x_discrete(expand = c(-1.1, 0)) + # to show the lower left name fully
labs(x = "", y = "", title = "")
选项 2(直接放置): 另一个选项是直接控制标签的移动量,而不是采取任何 jitter
碰巧给我们的东西。在这种情况下,我们知道我们想要移动具有相同 y 值的每对点。在我们需要同时担心 x 和 y 值的情况下,需要更复杂的逻辑,在同一重叠中有两个以上的点,and/or 我们需要移动接近但不完全相同的值。
library(dplyr)
# Create a new column that shifts pairs of points with the same y-value by +/- 0.25
df = df %>% group_by(Sum) %>%
mutate(SumNoOverlap = if(n()>1) Sum + c(-0.25,0.25) else Sum)
ggplot(df, aes(x = reorder(Firm, Sum, mean), y = SumNoOverlap)) +
geom_text(aes(label = Firm), size = 3) +
theme(axis.text.x = element_blank()) +
scale_x_discrete(expand = c(-1.1, 0)) + # to show the lower left name fully
labs(x = "", y = "", title = "")
注意: 要使抖动可重现,请在抖动绘图代码前添加 set.seed(153)
(或您想要的任何种子值)。