英文:
How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?
问题
在geom_violin()
的上方正确叠加一个使用不同但相关数据集的geom_errorbar()
,可以使用ggplot2
库来实现。以下是您可以尝试的代码:
library(ggplot2)
# 创建一个基础图
base_plot <- ggplot(data = df_detail,
aes(x = item,
y = bid_price)) +
geom_violin(fill = "gray90") +
geom_jitter(color = "darkorchid2",
size = 0.75,
alpha = 1,
width = 0.15) +
geom_point(data = df_summary,
aes(x = item,
y = award),
color = "red") +
theme_bw() +
coord_cartesian(ylim = c(0, 7000))
# 创建一个包含geom_errorbar()的图
errorbar_plot <- ggplot(data = df_summary,
mapping = aes(x = item,
ymin = mkt_low,
ymax = mkt_high)) +
geom_errorbar(width = 0.5) +
theme_void() # 使用一个空白的主题以避免覆盖基础图的外观
# 使用patchwork库来组合两个图
library(patchwork)
combined_plot <- base_plot / errorbar_plot
# 打印组合的图
print(combined_plot)
这段代码首先创建一个基础图,包括geom_violin()
、geom_jitter()
和geom_point()
,然后创建一个仅包含geom_errorbar()
的图,最后使用patchwork
库将两个图组合在一起,以获得所需的效果。希望这可以帮助您解决问题。
英文:
Question:
How do you properly stack a geom_errorbar()
that uses a different (but related!) dataset on top of geom_violin()
?
Setup
I ran an auction receiving many individual bid prices for shipping lanes. Afterwards, I selected 2 or 3 bids to create a weighted average award price. Additionally, for each lane, I received an external benchmarking service's low and high market estimate for the lane. In a single plot, I want to show:
geom_violin()
of the distribution of received bid prices.geom_jitter()
of the individual bid prices.geom_point()
of the single, weighted average/blended award.geom_errorbar()
(or related geom -- preferably shaded area usinggeom_rect()
) that shows the market estimate between low and high for that item.
To minimize repetition, I am using 2 dataframes, one with the numerous bid prices for each item, and one that contains just the blended award and market estimates:
df_detail <- data.frame(item = c("Item_1", "Item_1", "Item_1", "Item_1", "Item_1",
"Item_2", "Item_2", "Item_2", "Item_2", "Item_2",
"Item_3", "Item_3", "Item_3", "Item_3", "Item_3"),
bid_price = c(6678, 3236, 4674, 5487, 5490,
5800, 6678, 3827, 4674, 5487,
2266, 1195, 1225, 3285, 1350))
df_summary <- data.frame(item = c("Item_1", "Item_2", "Item_3"),
award = c(4278, 5844.32, 1244.31),
mkt_low = c(4603, 4619, 833),
mkt_high = c(5661, 5681, 1176))
Work So Far...
I know from other experience and reading that you can put the main dataset in the call to ggplot()
and add geom_*s()
, plus add separate datasets inside their own geom_*()
calls. I have no trouble with getting everything except the geom_errorbar()
in this call:
library(ggplot2)
ggplot(data = df_detail, # Primary dataset using all the bid prices
aes(x=item,
y = bid_price)) +
geom_violin(fill = "gray90") +
geom_jitter(color = "darkorchid2",
size = 0.75,
alpha = 1,
width = 0.15) +
geom_point(data = df_summary, # Add summary dataset with single award point.
aes(x = item,
y = award),
color = "red") +
theme_bw() +
coord_cartesian(ylim = c(0,7000))
...and I can separately create the geom_errorbars()
in their own plot containing the market lows and highs for each item:
ggplot(data = df_summary,
mapping = aes(x = item,
ymin = mkt_low,
ymax = mkt_high)) +
geom_errorbar(width = 0.5) +
theme_bw() +
coord_cartesian(ylim = c(0,7000))
The Problem
I can't put them together in the same plot:
ggplot(data = df_detail,
aes(x=item,
y = bid_price)) +
geom_violin(fill = "gray90") +
geom_jitter(color = "darkorchid2",
size = 0.75,
alpha = 1,
width = 0.15) +
geom_point(data = df_summary,
aes(x = item,
y = award),
color = "red") +
geom_errorbar(data = df_summary, # I am adding this geom_* call!!!!
mapping = aes(x = item,
ymin = mkt_low,
ymax = mkt_high),
width = 0.5) +
theme_bw() +
coord_cartesian(ylim = c(0,7000))
The above errors for me as seen below in the trace. However, I'm confused because I didn't have a problem with the geom_point()
call which worked earlier. I don't understand the geom_errorbar()
looking for the object bid_price
which is part of df_detail
. If I run rlang::last_trace()
, my skills are not good enough to decipher this usefully:
I feel I have some major misconception here, and I appreciate any help offered. Thank you in advance.
答案1
得分: 2
因为你在第1行的ggplot()
调用中设置了data = df_detail
和aes(y = bid_price)
,它们将被继承为所有后续geom_*
的默认值。这对于geom_errorbar()
中的aes(y = )
参数来说也是如此,不论你是否提供了自定义的data
和aes(x)
参数给误差条。
要获得你想要的效果,要么在每个geom
中设置y
参数而不是在ggplot(aes())
调用中设置,要么简单地将geom_errorbar
中的aes()
映射中的y
参数设置为NULL。
ggplot(data = df_detail,
aes(x = item, y = bid_price)) +
geom_violin(fill = "gray90") +
geom_jitter(color = "darkorchid2",
size = 0.75,
alpha = 1,
width = 0.15) +
geom_point(data = df_summary,
aes(x = item, y = award),
color = "red") +
geom_errorbar(data = df_summary,
mapping = aes(x = item, y = NULL, ymin = mkt_low, ymax = mkt_high),
width = 0.5) +
theme_bw() +
coord_cartesian(ylim = c(0, 7000))
[1]: https://i.stack.imgur.com/qI6db.png
英文:
Because you set data =df_detail
and aes(y = bid_price)
in the ggplot()
call on line 1, they will be inherited as the default values for all subsequent geom_*.
This is true for the aes(y = )
parameter in your geom_errorbar()
, regardless of the custom data
and aes(x)
parameter provided to the error bar.
To get what you want, either set the y parameter in each geom rather than in the ggplot(aes())
call, or simply set the y parameter of the aes()
mapping in the geom_errorbar
to NULL.
ggplot(data = df_detail,
aes(x=item,
y = bid_price)) +
geom_violin(fill = "gray90") +
geom_jitter(color = "darkorchid2",
size = 0.75,
alpha = 1,
width = 0.15) +
geom_point(data = df_summary,
aes(x = item,
y = award),
color = "red") +
geom_errorbar(data = df_summary,
mapping = aes(x = item,
y = NULL, # Here!
ymin = mkt_low,
ymax = mkt_high),
width = 0.5) +
theme_bw() +
coord_cartesian(ylim = c(0,7000))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论