ggplot:防止年终数据显示为下一年

问题描述 投票:1回答:2

这似乎是一个简单的问题,但我找不到一个简单的方法来做到这一点,类似的问题似乎没有解决我的问题。

我正在绘制年终数据,并希望它在x轴上显示为当年,而不是第二年。例如,2015年12月31日的数据反映了2015年发生的情况,而不是2016年,但情节将显示为2016年。

我可以改变数据并在变异列中添加仅年份值(2015年12月31日变为2015)并使用它来绘制数据集,但我希望有更简单的事情,以防我想要绘制其他时间期间(季度,月份等)。

那2个问题:

1)是否有一种简单的方法可以自动绘制年终数据以表示其发生的年份而不是下一年?

2)当我试图调整x轴刻度时,为什么ggplot会删除2行,导致绘图更糟(test_p2)?

可重复的例子

library(ggplot2)
library(lubridate)

# Sample data
mydates   <- as.Date(c( "2015-12-31", "2016-12-31", "2017-12-23", "2015-12-31", "2016-12-31", "2017-12-23"))
variables <- c(rep("A", 3), rep("B", 3))
values    <- c(2, 4, -4, -5, -10, 5)
test_df   <- data.frame(mydates, variables, values)

# plot
test_p <- ggplot(test_df, aes(x = mydates, y = values, fill = variables)) + geom_col(position = "dodge")
test_p

enter image description here

调整x轴刻度:

BeginPlotDate   = "2015-12-31"
EndPlotDate     = "2017-12-23"

test_p2 <- test_p + scale_x_date(date_breaks = "1 year",
                                 date_labels = "%Y",
                                 limits      = as.Date(c(BeginPlotDate, EndPlotDate))
                                 )
test_p2

enter image description here

r plot ggplot2 lubridate
2个回答
1
投票

你通常不应该一次问两个问题,但无论如何,这里有两个答案:

问题1

会发生什么事情是ggplot2将日期四舍五入到最接近的一年,那就是下一年。我认为解决这个问题的最简单方法是在aes()声明中简单地减去12个月:

test_p <- ggplot(test_df,
                 aes(x = mydates %m-% months(12),
                     y = values, fill = variables)) + 
          geom_col(position = "dodge")
test_p

enter image description here

唯一的缺点是现在你需要手动调整x轴的标题,但这很简单,例如与xlab()

test_p + xlab("my dates")

enter image description here

问题2

您将x轴的起点设置为“2015-12-31”,这正是ggplot所做的。您需要将起点设置为较早的日期(大约提前6个月),以便为要在其中绘制的条形图留出足够的空间。 (在这里,我实际上必须在18个月之前设置它,因为我也从日期中减去了12个月,见上文。)

BeginPlotDate   = "2014-06-01"
EndPlotDate     = "2017-08-01"

test_p2 <- test_p + scale_x_date(date_breaks = "1 year",
                                 date_labels = "%Y",
                                 limits      = as.Date(c(BeginPlotDate, EndPlotDate))
)
test_p2

enter image description here


1
投票

这个问题有一个相当简单的解决方案:只需使用year(mydates)

library(ggplot2)
library(lubridate)

ggplot(test_df, aes(x = year(mydates), y = values, fill = variables)) + 
  geom_col(position = "dodge")

enter image description here

当绘制DatePOSIXct时,ggplot2采用连续比例,通过在适当的位置放置标记良好的刻度标记来适当地形成,例如,2016-01-01将标记为“2016”。因此,如果您的数据点的x值为2015-12-31,则会在2016-01-01刻度线附近绘制。这对于每日或每周数据很有用,但在您的用例中则不行。

Edit

OP指出他需要一个日期轴,因为他也希望绘制月度和季度数据。

如果OP希望使用连续日期轴在一个图中叠加月度,季度和年度数据,那么我强烈建议不要使用条形图来实现此目的,尤其是在躲闪时。

条形图通常用于离散数据。条的高度传达信息。通常,宽度没有意义,可以任意选择或美学上令人愉悦。

如果OP坚持日期轴,则宽度应具有含义。例如,水平扩展可以传达每个值被分配给的时间段的信息,例如,

ggplot(test_df, aes(x = floor_date(mydates, "year"), xend = mydates, 
                    y = values, yend = values, colour = variables)) + 
  geom_segment(size = 1) +
  theme_bw()

enter image description here

这里,线段从年初开始并延伸到给定的结束日期。这可视化values代表年度价值。躲闪对她没有任何意义,所以颜色代码是variables的唯一区别。

一个更复杂的例子(使用特别组成的数据)在一个图表中显示月度值,季度和年度平均值:

ggplot(month_df) + 
  aes(x = mydates, xend = floor_date(mydates, first(period)), 
      xmin = floor_date(mydates, first(period)), xmax = mydates,
      y = values, yend = values, ymin = 0, ymax = values, 
      fill = variables, shape = variables) + 
  geom_rect(data = year_df, alpha = 0.5)  +
  geom_segment(aes(colour = variables), data = quarter_df, size = 1) + 
  geom_point() +
  theme_bw()

enter image description here

然而,图表相当复杂,图表的信息难以解释和察觉。

Data

library(data.table)
# create monthly dummy data
month_df <- data.table(
  # last day of month
  mydates = rep(seq(as.Date("2015-02-01"), length.out = 36L, by = "month") - days(1L), 2L),
  variables = rep(LETTERS[1:2], each = 36L),
  values = c(sinpi((1:36) / 18), cospi((1:36) / 12)),
  period = "month"
)
# aggregate by quarter
quarter_df <- month_df[, .(values = mean(values), period = "quarter"), 
     by = .(mydates = ceiling_date(mydates, "quarter") - days(1L), variables)]
# aggregate by year
year_df <- month_df[, .(values = mean(values), period = "year"), 
     by = .(mydates = ceiling_date(mydates, "year") - days(1L), variables)]
© www.soinside.com 2019 - 2024. All rights reserved.