【问题标题】:Change plotting order of bars in ggplot2更改 ggplot2 中条形图的绘制顺序
【发布时间】:2018-02-16 16:54:44
【问题描述】:

我正在为修订稿准备一个附录图,我需要在其中提供年份和地点之间几个变量的年内范围(变异性)的信息。

我认为最简洁的方法(我有 7 个站点、21 年和 5 个变量...)是使用 coord_polar 的玫瑰图。然而,我偶然发现了一些让我对 ggplot 感到沮丧的事情——默认的排序假设。虽然因子很容易根据某些值重新排序,但这似乎只能以 固定 方式工作:据我所知,该顺序需要应用于整个数据帧。

在此图中,排序需要取决于在年份之间变化的值,因此colourfill 值需要在面板内按绘图顺序进行更改。

为了演示,我创建了一个可重现的示例,代码如下(图示为它不应该工作的方式)

基本上,我总是需要首先绘制在给定年份内具有最小值的站点(在中心),然后按照原始值的顺序向外绘制其他站点的价值增加(请参阅@987654327 @ 和 diff 数据框的列)。换句话说,有些年份站点 a 将位于中心,有些年份站点 c 将位于中心,等等。

任何帮助将不胜感激。

library('ggplot2')
library('reshape2')
library("plyr")

## reproducible example of problem: create dummy data
madeup <- data.frame(Year = rep(2000:2015, each=20), Site=rep(c("a","b","c","d"), each=5, times=16),
                     var1 = rnorm(n=16*20, mean=20, sd=5), var2= rnorm(n=16*20, mean=50, sd=1))

## create ranges of the data by Year and Site
myRange <- function(dat) {range=max(dat, na.rm=TRUE)-min(dat,na.rm = TRUE)}
vardf <- ddply(madeup, .(Site, Year), summarise, var1=myRange(var1),
               var2=myRange(var2))

varmelt <- melt(vardf, id.vars = c("Site","Year"))
varmelt$Site <- as.character(varmelt$Site) # this to preserve the new order when rbind called
varmelt <- by(varmelt, list(varmelt$Year, varmelt$variable), function(x) {x <- x[order(x$value),]
x$order <- 1:nrow(x)
return(x)})
varmelt <- do.call(rbind, varmelt)

## create difference between these values so that each site gets plotted cumulatively on the rose plot
##  (otherwise areas close to the centre become uninterpretable)
vartest <- by(varmelt, list(varmelt$Year, varmelt$variable), function(x) {
  x$diff <- c(x$value[1], diff(x$value))
  return(x)
})
vartest <- do.call(rbind,vartest)

## plot rose plot to display how ranges in variables vary by year and between sites
## for this test example we'll just take one variable, but the idea is to facet by variable
max1 <- max(vartest$value[vartest$variable=='var1'])
yearlength <- length(2000:2015)
ggplot(vartest[vartest$variable=="var1",], aes(x=factor(Year), y=diff)) +
  theme_bw() +
  geom_hline(yintercept = seq(0,max1, by=1), size=0.3, col="grey60",lty=3) +
  geom_vline(xintercept=seq(1,yearlength,1), size=0.3, col='grey30', lty=2) +
  geom_bar(stat='identity', width=1, size=0.5, aes(col=Site, fill=Site)) +
  scale_x_discrete() +
  coord_polar() +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())

【问题讨论】:

  • 这并不能真正解决您关于绘图顺序的问题,但对于手头的问题,我真的会考虑使用不同的几何图形,可能是 point。在我看来,很容易将您的预期情节误解为堆积条形而不是......过度绘制的条形,从而导致混乱。
  • 或者,如果你想坚持使用条形,你可以在y轴上使用value,将位置设置为identity,填充到NA,然后在条形轮廓上使用颜色.
  • 非常感谢@MikkoMarttila!我曾尝试在geom_colgeom_bar 上阅读很多内容,但并没有简单地遇到这个选项组合来获得我需要的东西 - 如果您知道任何可以说明这一点的资源,或者一般解释这些功能以及他们在一份文件中的选择,很高兴知道。 PS是的,我已经尝试了很多点绘图等,但是为了展示我需要的东西,这种方法似乎是最好的,尤其是在区分时。与填充区域相比,7 组的点颜色在视觉上真的很难......我会看看共同作者的感受!
  • 说实话,我也有点惊讶,数据的顺序很重要。所以@EmmaWiik 我不确定我是否可以针对该特定问题推荐任何资源!但是R for Data Science by Grolemund and Wickham 值得一试,如果您还没有的话。

标签: r ggplot2 bar-chart pie-chart r-factor


【解决方案1】:

只要你不使用堆叠条(position = "stack",这是geom_bar 的默认值),ggplot2 实际上将是use the order of the rows in your data for the plotting order。因此,您需要做的就是使用 y 轴的原始值(而不是累积差异值)以及position = "identity",并在绘图之前将数据从最大到最小value 排序

ordered_data <- vartest[order(-vartest$value), ]

ggplot(ordered_data, aes(factor(Year), value)) +
  geom_col(aes(fill = Site), position = "identity", width = 1) +
  coord_polar() +
  facet_wrap(~ variable)

reprex package (v0.2.0) 于 2018 年 2 月 17 日创建。

PS。在为示例生成随机数据时,请考虑使用set.seed,以便可以准确地再现您的结果。

【讨论】:

    【解决方案2】:

    您可以从最大站点的单个地块开始,然后将较小的站点分层,如下所示:

    a <- ggplot(vartest[vartest$variable=="var1"& vartest$order==4,], aes(x=factor(Year), y=value,group=order)) +
      theme_bw() +
      geom_hline(yintercept = seq(0,max1, by=1), size=0.3, col="grey60",lty=3) +
      geom_vline(xintercept=seq(1,yearlength,1), size=0.3, col='grey30', lty=2) +
      geom_bar(stat='identity', width=1, size=0.5, aes(col=Site, fill=Site)) +
      scale_x_discrete() +
      coord_polar() +
      theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
    
    b <- a + geom_bar(data = vartest[vartest$variable=="var1"& vartest$order==3,],
                stat='identity', width=1, size=0.5, aes(x=factor(Year), y=value,col=Site, fill=Site))
    
    c <- b + geom_bar(data = vartest[vartest$variable=="var1"& vartest$order==2,],
                stat='identity', width=1, size=0.5, aes(x=factor(Year), y=value,col=Site, fill=Site))
    
    c + geom_bar(data = vartest[vartest$variable=="var1"& vartest$order==1,],
                stat='identity', width=1, size=0.5, aes(x=factor(Year), y=value,col=Site, fill=Site))
    

    这会产生以下结果:

    这是你想要的吗?

    【讨论】:

    • 感谢您的建议。我知道这个选项,但由于我有很多变化,我尽力避免它!
    猜你喜欢
    • 2016-04-15
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 2020-10-18
    相关资源
    最近更新 更多