我正在为修改后的手稿准备一个附录图,其中我需要提供年份和地点之间几个变量的年内范围(可变性)的信息。
我想出了最整洁的方法(我有7个网站,21年,5个变量…)将使用玫瑰图
coord_polar
. 然而,我偶然发现了一些令我一直对ggplot感到沮丧的东西——默认的排序假设。虽然因子很容易根据某个值重新排序,但这似乎只适用于
固定的
时尚:据我所知,订单需要应用于整个数据框架。
在该图中,排序需要取决于年与年之间变化的值,因此
colour
和
fill
值需要在面板内按打印顺序更改。
为了演示,我创建了一个可复制的示例,代码如下(以不应该工作的方式绘制)
基本上,我总是需要首先绘制给定年份内具有最小值的场地(中间),然后向外绘制其他场地的增值,按照原值的顺序(参见
order
和
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())