How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

huangapple go评论107阅读模式
英文:

How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

问题

geom_violin()的上方正确叠加一个使用不同但相关数据集的geom_errorbar(),可以使用ggplot2库来实现。以下是您可以尝试的代码:

  1. library(ggplot2)
  2. # 创建一个基础图
  3. base_plot <- ggplot(data = df_detail,
  4. aes(x = item,
  5. y = bid_price)) +
  6. geom_violin(fill = "gray90") +
  7. geom_jitter(color = "darkorchid2",
  8. size = 0.75,
  9. alpha = 1,
  10. width = 0.15) +
  11. geom_point(data = df_summary,
  12. aes(x = item,
  13. y = award),
  14. color = "red") +
  15. theme_bw() +
  16. coord_cartesian(ylim = c(0, 7000))
  17. # 创建一个包含geom_errorbar()的图
  18. errorbar_plot <- ggplot(data = df_summary,
  19. mapping = aes(x = item,
  20. ymin = mkt_low,
  21. ymax = mkt_high)) +
  22. geom_errorbar(width = 0.5) +
  23. theme_void() # 使用一个空白的主题以避免覆盖基础图的外观
  24. # 使用patchwork库来组合两个图
  25. library(patchwork)
  26. combined_plot <- base_plot / errorbar_plot
  27. # 打印组合的图
  28. 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 using geom_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:

  1. df_detail &lt;- data.frame(item = c(&quot;Item_1&quot;, &quot;Item_1&quot;, &quot;Item_1&quot;, &quot;Item_1&quot;, &quot;Item_1&quot;,
  2. &quot;Item_2&quot;, &quot;Item_2&quot;, &quot;Item_2&quot;, &quot;Item_2&quot;, &quot;Item_2&quot;,
  3. &quot;Item_3&quot;, &quot;Item_3&quot;, &quot;Item_3&quot;, &quot;Item_3&quot;, &quot;Item_3&quot;),
  4. bid_price = c(6678, 3236, 4674, 5487, 5490,
  5. 5800, 6678, 3827, 4674, 5487,
  6. 2266, 1195, 1225, 3285, 1350))
  7. df_summary &lt;- data.frame(item = c(&quot;Item_1&quot;, &quot;Item_2&quot;, &quot;Item_3&quot;),
  8. award = c(4278, 5844.32, 1244.31),
  9. mkt_low = c(4603, 4619, 833),
  10. mkt_high = c(5661, 5681, 1176))

How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

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:

  1. library(ggplot2)
  2. ggplot(data = df_detail, # Primary dataset using all the bid prices
  3. aes(x=item,
  4. y = bid_price)) +
  5. geom_violin(fill = &quot;gray90&quot;) +
  6. geom_jitter(color = &quot;darkorchid2&quot;,
  7. size = 0.75,
  8. alpha = 1,
  9. width = 0.15) +
  10. geom_point(data = df_summary, # Add summary dataset with single award point.
  11. aes(x = item,
  12. y = award),
  13. color = &quot;red&quot;) +
  14. theme_bw() +
  15. coord_cartesian(ylim = c(0,7000))

How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

...and I can separately create the geom_errorbars() in their own plot containing the market lows and highs for each item:

  1. ggplot(data = df_summary,
  2. mapping = aes(x = item,
  3. ymin = mkt_low,
  4. ymax = mkt_high)) +
  5. geom_errorbar(width = 0.5) +
  6. theme_bw() +
  7. coord_cartesian(ylim = c(0,7000))

How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

The Problem

I can't put them together in the same plot:

  1. ggplot(data = df_detail,
  2. aes(x=item,
  3. y = bid_price)) +
  4. geom_violin(fill = &quot;gray90&quot;) +
  5. geom_jitter(color = &quot;darkorchid2&quot;,
  6. size = 0.75,
  7. alpha = 1,
  8. width = 0.15) +
  9. geom_point(data = df_summary,
  10. aes(x = item,
  11. y = award),
  12. color = &quot;red&quot;) +
  13. geom_errorbar(data = df_summary, # I am adding this geom_* call!!!!
  14. mapping = aes(x = item,
  15. ymin = mkt_low,
  16. ymax = mkt_high),
  17. width = 0.5) +
  18. theme_bw() +
  19. 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:
How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

I feel I have some major misconception here, and I appreciate any help offered. Thank you in advance.

答案1

得分: 2

因为你在第1行的ggplot()调用中设置了data = df_detailaes(y = bid_price),它们将被继承为所有后续geom_*的默认值。这对于geom_errorbar()中的aes(y = )参数来说也是如此,不论你是否提供了自定义的dataaes(x)参数给误差条。

要获得你想要的效果,要么在每个geom中设置y参数而不是在ggplot(aes())调用中设置,要么简单地将geom_errorbar中的aes()映射中的y参数设置为NULL。

  1. ggplot(data = df_detail,
  2. aes(x = item, y = bid_price)) +
  3. geom_violin(fill = "gray90") +
  4. geom_jitter(color = "darkorchid2",
  5. size = 0.75,
  6. alpha = 1,
  7. width = 0.15) +
  8. geom_point(data = df_summary,
  9. aes(x = item, y = award),
  10. color = "red") +
  11. geom_errorbar(data = df_summary,
  12. mapping = aes(x = item, y = NULL, ymin = mkt_low, ymax = mkt_high),
  13. width = 0.5) +
  14. theme_bw() +
  15. coord_cartesian(ylim = c(0, 7000))

How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

  1. [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.

  1. ggplot(data = df_detail,
  2. aes(x=item,
  3. y = bid_price)) +
  4. geom_violin(fill = &quot;gray90&quot;) +
  5. geom_jitter(color = &quot;darkorchid2&quot;,
  6. size = 0.75,
  7. alpha = 1,
  8. width = 0.15) +
  9. geom_point(data = df_summary,
  10. aes(x = item,
  11. y = award),
  12. color = &quot;red&quot;) +
  13. geom_errorbar(data = df_summary,
  14. mapping = aes(x = item,
  15. y = NULL, # Here!
  16. ymin = mkt_low,
  17. ymax = mkt_high),
  18. width = 0.5) +
  19. theme_bw() +
  20. coord_cartesian(ylim = c(0,7000))

How do I add geom_errorbars() using a separate dataset to an existing geom_violin() dataset in ggplot2?

huangapple
  • 本文由 发表于 2023年3月12日 11:12:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710864.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定