简体   繁体   English

ggplot2 - 如何使用 geom_bar 绘制时间长度?

[英]ggplot2 - How to plot length of time using geom_bar?

I am trying to show different growing season lengths by displaying crop planting and harvest dates at multiple regions.我试图通过显示多个地区的作物种植和收获日期来显示不同的生长季节长度。

My final goal is a graph that looks like this:我的最终目标是一个看起来像这样的图表:

在此处输入图片说明

which was taken from an answer to this question .这是从这个问题的答案中提取的。 Note that the dates are in julian days (day of year).请注意,日期以儒略日(一年中的某一天)为单位。

My first attempt to reproduce a similar plot is:我第一次尝试重现类似的情节是:

library(data.table)
library(ggplot2)

mydat <- "Region\tCrop\tPlanting.Begin\tPlanting.End\tHarvest.Begin\tHarvest.End\nCenter-West\tSoybean\t245\t275\t1\t92\nCenter-West\tCorn\t245\t336\t32\t153\nSouth\tSoybean\t245\t1\t1\t122\nSouth\tCorn\t183\t336\t1\t153\nSoutheast\tSoybean\t275\t336\t1\t122\nSoutheast\tCorn\t214\t336\t32\t122"

# read data as data table
mydat <- setDT(read.table(textConnection(mydat), sep = "\t", header=T))

# melt data table
m <- melt(mydat, id.vars=c("Region","Crop"), variable.name="Period", value.name="value")

# plot stacked bars
ggplot(m, aes(x=Crop, y=value, fill=Period, colour=Period)) + 
  geom_bar(stat="identity") +
  facet_wrap(~Region, nrow=3) +
  coord_flip() +
  theme_bw(base_size=18) +
  scale_colour_manual(values = c("Planting.Begin" = "black", "Planting.End" = "black",
                                 "Harvest.Begin" = "black", "Harvest.End" = "black"), guide = "none")

在此处输入图片说明

However, there's a few issues with this plot:然而,这个情节有几个问题:

  1. Because the bars are stacked, the values on the x-axis are aggregated and end up too high - out of the 1-365 scale that represents day of year.因为条形是堆叠的,所以 x 轴上的值被聚合并最终变得太高 - 超出了代表一年中某天的 1-365 比例。

  2. I need to combine Planting.Begin and Planting.End in the same color, and do the same to Harvest.Begin and Harvest.End .我需要将Planting.BeginPlanting.End组合成相同的颜色,并对Harvest.BeginHarvest.End做同样的Harvest.End

  3. Also, a "void" (or a completely uncolored bar) needs to be created between Planting.Begin and Harvest.End .此外,需要在Planting.BeginHarvest.End之间创建一个“空白”(或完全无色的条)。

Perhaps the graph could be achieved with geom_rect or geom_segment , but I really want to stick to geom_bar since it's more customizable (for example, it accepts scale_colour_manual in order to add black borders to the bars).也许可以使用geom_rectgeom_segment来实现图形,但我真的想坚持使用geom_bar因为它更具可定制性(例如,它接受scale_colour_manual以便为条形添加黑色边框)。

Any hints on how to create such graph?有关如何创建此类图的任何提示?

I don't think this is something you can do with a geom_bar or geom_col .我不认为这是你可以用geom_bargeom_col做的geom_col A more general approach would be to use geom_rect to draw rectangles.更通用的方法是使用geom_rect绘制矩形。 To do this, we need to reshape the data a bit为此,我们需要稍微重塑数据

plotdata <- mydat %>% 
  dplyr::mutate(Crop = factor(Crop)) %>% 
  tidyr::pivot_longer(Planting.Begin:Harvest.End, names_to="period") %>% 
  tidyr::separate(period, c("Type","Event")) %>% 
  tidyr::pivot_wider(names_from=Event, values_from=value)


#    Region      Crop    Type     Begin   End
#    <chr>       <fct>   <chr>    <int> <int>
#  1 Center-West Soybean Planting   245   275
#  2 Center-West Soybean Harvest      1    92
#  3 Center-West Corn    Planting   245   336
#  4 Center-West Corn    Harvest     32   153
#  5 South       Soybean Planting   245     1
#  ...

We've used tidyr to reshape the data so we have one row per rectangle that we want to draw and we've also make Crop a factor.我们使用tidyr来重塑数据,因此我们要绘制的每个矩形都有一行,并且我们还使 Crop 成为一个因素。 We can then plot it like this然后我们可以像这样绘制它

ggplot(plotdata) + 
  aes(ymin=as.numeric(Crop)-.45, ymax=as.numeric(Crop)+.45, xmin=Begin, xmax=End, fill=Type) + 
  geom_rect(color="black") + 
  facet_wrap(~Region, nrow=3) + 
  theme_bw(base_size=18) +
  scale_y_continuous(breaks=seq_along(levels(plotdata$Crop)), labels=levels(plotdata$Crop))

在此处输入图片说明

The part that's a bit messy here that we are using a discrete scale for y but geom_rect prefers numeric values, so since the values are factors now, we use the numeric values for the factors to create ymin and ymax positions.这里有点混乱的部分是我们对y使用离散比例但geom_rect更喜欢数值,因此由于现在这些值是因子,我们使用因子的数值来创建 ymin 和 ymax 位置。 Then we need to replace the y axis with the names of the levels of the factor.然后我们需要用因子水平的名称替换 y 轴。

If you also wanted to get the month names on the x axis you could do something like如果您还想在x轴上获取月份名称,您可以执行以下操作

dateticks <- seq.Date(as.Date("2020-01-01"), as.Date("2020-12-01"),by="month")
# then add this to you plot
  ... + 
    scale_x_continuous(breaks=lubridate::yday(dateticks),
                       labels=lubridate::month(dateticks, label=TRUE, abbr=TRUE))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM