【问题标题】:Shading area under a line plot (ggplot2) with 2 different colours具有 2 种不同颜色的线图 (ggplot2) 下的阴影区域
【发布时间】:2021-06-08 01:01:27
【问题描述】:

所以我有一个包含 2 个变量、一个日期和一个美元价值(盈利或亏损)的简单数据集(实际上是表格)。我正在尝试绘制一个损益图,并让区域 y>0 以绿色阴影显示,y

数据:根据要求,我收集数据的日期包括 4 月 14 日至 9 月 1 日。

dput(upl2$Unrealised.Profit.or.Loss)
c(87.5, -46, 163.5, 194.5, 251.5, 392, 276.5, 424, 354.5, 194, 
152, 104, 2, 0, 113, 78.5)

教授或损失代码:

y <- upl2$Unrealised.Profit.or.Loss
loss <- y < 0 
prof <- y > 0
even <- y == 0 

剧情代码:

ggplot(data = upl2, aes(x=Date, y=Unrealised.Profit.or.Loss, group=1)) + 
geom_point() + 
theme(axis.text.x = element_text(angle = 60, vjust = 0.5, hjust = 0.5)) + 
geom_line(size=.75) + 
geom_hline(yintercept=0, size=.5, color = "Blue") + 
labs(x = "Date", y = "Unrealised Profit or Loss", title = "Unreaslied Profit or Loss as of 7/6/2021")

任何建议都会很棒,
干杯

【问题讨论】:

标签: r ggplot2


【解决方案1】:

虽然对相交线之间的区域进行着色可能听起来很容易,但据我所知并非如此,而且我多次为这个问题苦苦挣扎。原因是通常交点(在您的情况下是曲线的零点)不是数据的一部分。因此,当尝试使用geom_areageom_ribbon 对区域进行着色时,我们最终会在交点处出现重叠区域。这个问题的更详细解释可以在这个post 中找到,它还通过使用approx 提供了一个解决方案。

应用于您的用例

  1. 将您的 Date 变量转换为我们希望在日期之间进行近似的日期时间。
  2. 使用approx 创建一个辅助数据框,它在日期之间进行插值并将“零”或交点添加到数据中。设置点数n 需要反复试验,以确保肉眼看不到重叠。在我看来 n=500 工作正常。
  3. 为损失和利润添加单独的变量,并将approx 返回的数字转换回日期时间,例如使用lubridate::as_datetime
  4. 通过两个单独的geom_ribbons 绘制阴影区域。

由于您没有提供示例数据,我的示例代码使用了一些随机的假数据:

library(ggplot2)
library(dplyr)
library(lubridate)

# Prepare example data

set.seed(42)

Date <- seq.Date(as.Date("2021-05-16"), as.Date("2021-06-07"), by = "day")
Unrealised.Profit.or.Loss <- runif(length(Date), -1, 1)

upl2 <- data.frame(Date, Unrealised.Profit.or.Loss)

# Prepare helper dataframe to draw the ribbons
upl2$Date <- as.POSIXct(upl2$Date)

upl3 <- data.frame(approx(upl2$Date,  upl2$Unrealised.Profit.or.Loss, n = 500))
names(upl3) <- c("Date", "Unrealised.Profit.or.Loss")

upl3 <- upl3 %>% 
  mutate(
    Date = lubridate::as_datetime(Date),
    loss = Unrealised.Profit.or.Loss < 0,
    profit = ifelse(!loss, Unrealised.Profit.or.Loss, 0),
    loss = ifelse(loss, Unrealised.Profit.or.Loss, 0))

ggplot(data = upl2, aes(x = Date, y = Unrealised.Profit.or.Loss, group = 1)) +
  geom_ribbon(data = upl3, aes(ymin = 0, ymax = loss), fill = "red") +
  geom_ribbon(data = upl3, aes(ymin = 0, ymax = profit), fill = "green") +
  geom_point() +
  geom_line(size = .75) +
  geom_hline(yintercept = 0, size = .5, color = "Blue") +
  scale_x_datetime(date_breaks = "day", date_labels = "%B %d") +
  theme(axis.text.x = element_text(angle = 60, vjust = 0.5, hjust = 0.5)) +
  labs(x = "Date", y = "Unrealised Profit or Loss", title = "Unreaslied Profit or Loss as of 7/6/2021")

【讨论】:

  • 绝对传奇,这正是我所寻找的。再次感谢!
  • 我收到此错误,Error in as.POSIXlt.character(as.character(x), ...) : character string is not in a standard unambiguous format。以及Error in seq.int(0, to0 - from, by) : 'to' must be a finite number 只是想知道这些和这条线是什么意思,upl3 &lt;- data.frame(approx(upl2$Date, upl2$Unrealised.Profit.or.Loss, n = 500))。 n=500 代表什么?再次欢呼
  • 我现在想我通过设置 upl3 的观察值来理解 n=500 的含义,但是无论我在 Error in seq.int(0, to0 - from, by) : 'to' must be a finite number 中输入的任何数字都会弹出,不确定这实际上来自哪里跨度>
  • 刚刚修复了错误。干杯再次成为一个绝对的传奇!唯一的问题是它确实准确地绘制了 upl2 数据的损益,而不是 upl3 的近似值,这是否意味着正在发生?
  • 不客气。嗯。你说的“它没有准确地绘制”是什么意思?但听起来它与我提供的解决方案无关。也许您可以对帖子进行编辑以澄清问题或提出新问题?最佳 S.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
  • 2016-06-29
相关资源
最近更新 更多