R条形图:指定基于日期的x轴的间隔

时间:2017-12-15 06:55:38

标签: r plot

我一直在制作不同的图表集,所有图表都在R base中。我有一个问题,但有条形图。我已经格式化了x轴以按年显示日期,但是,多年来会出现多次。我希望每年只出现一次。

这是我的示例代码:

library(quantmod)
start <- as.Date("01/01/2010", "%d/%m/%Y")

#Download FRED data
tickers <- c("WTISPLC", "DCOILBRENTEU")
fred <- lapply(tickers, function(sym) {na.omit(getSymbols(sym, src="FRED", auto.assign=FALSE, return.class = "zoo"))})
df <- do.call(merge, fred)

#Subset for start date
df <- subset(df, index(df)>=start)

#Create bar plot
par(mar = c(5,5,5,5))

barplot(df[,2], names.arg=format(index(df), "%Y"), ann=FALSE, bty="n", tck=-0, col=1:1,  border=NA, space=0); title(main="Example chart", ylab="y-axis")

这个例子应该是可重复的,并清楚地表明我的意思。现在,我一直在研究如何添加单独的x轴以及如何定义该轴。所以,我试图添加以下代码:

#Plot bars but without x-axis
barplot(df[,2], names.arg=format(index(df), "%Y"), ann=FALSE, bty="n", tck=-0, xaxt="n", col=1:1,  border=NA, space=0); title(main="Example chart", ylab="y-axis")

# Set x-axis parameters
x_min <- min(index(df))
x_max <- max(index(df))
xf="%Y"

#Add x-axis
axis.Date(1, at=seq(as.Date(x_min), x_max, "years"), format=xf, las=1, tck=-0)

这不会给我一个错误信息,但它在绘制x轴方面也绝对没有。

请不要为ggplot提供解决方案。即使我喜欢ggplot,这些条形图对我来说也是一个更大的项目的一部分,都使用R base,我现在不想将ggplot引入这个项目。

enter image description here

谢谢!

2 个答案:

答案 0 :(得分:0)

如果您不限于barplot,则可以在屏幕后面使用plot.zoo使用以下非常简单的解决方案:

# only use what you want, and avoid multiple plots
df2 <- df[ , 2]

# use zoo.plot's functionality
plot(df2, main = "Example Chart", ylab = "y-axis", xlab = "")

这产生以下图:

enter image description here

我知道这不是一个条形图,但我不知道这里会添加一个条形图。请告诉我,这是否是你想要的。

编辑1

如果您确实想使用barplot,可以使用以下代码:

### get index of ts in year format
index_y <- format(index(df), "%Y")

### logical vector with true if it is the start of a new year
index_u <- !duplicated(index_y)

### index of start of new year for tick marks
at_tick <- which(index_u)

### label of start of new year
labels <- index_y[index_u]

### draw barplot without X-axis, and store in bp
### bp (bar midpoints) is used to set the ticks right with the axis function
bp <- barplot(df[,2], xaxt = "n", ylab= "y-axis") 
axis(side = 1, at = bp[at_tick] , labels = labels)

产生以下情节:

enter image description here

请告诉我,这是否是你想要的。

编辑2

在解释为什么刻度线和标签在左侧组合在一起时,我们需要考虑两位信息。

(1)在barplot中,space定义每个条形前的空间量(作为平均条宽的一部分)。在我们的例子中,它默认为零(有关详细信息,请参阅?barplot)。在下图中,我们使用0.0,0.5和2.0

的空格

(2)Barplot返回一个数字向量,其中绘制了条形图的中点(有关详细信息,请再次参阅帮助页面)。我们可以使用这些中点向图表添加信息,就像我们在以下摘录中所做的那样:在 bp 中存储barplot的结果后,我们使用 bp 设置刻度:axis(... at = bp[at_tick] ... )

当我们添加空格时,条形中点的位置会发生变化。因此,当我们想在添加空格后使用条形中点时,我们需要确保我们拥有正确的信息。简单地说,使用barplot返回的向量和添加空格的调用。如果你不这样做,图表就会搞砸了。在下面的内容中,如果您继续使用(空格= 0)调用的条形中点,并且增加了空格,则标记和标签将分组在左侧。

下面,我将您的数据限制在2017年的3个月内。 在顶层3绘制条形图,space等于0.0,0.5和2.0。用于计算蜱和标签位置的信息将重新计算并保存在每个图中。

在底层,绘制了相同的3个条形图,但用于绘制刻度线和标签的信息仅使用第一个绘图(空格= 0.0)创建

# Subset for NEW start for illustration of space and bp
start2 <- as.Date("01/10/2017", "%d/%m/%Y")
df2 <- subset(df, index(df)>=start2)

### get index of ts in month format, define ticks and labels
index_y2 <- format(index(df2), "%m")
at_tick2 <- which(!duplicated(index_y2))
labels2 <- index_y2[!duplicated(index_y2)]

par(mfrow = c(2,3))
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.0, main ="Space = 0.0") 
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.5, main ="Space = 0.5") 
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 2.0, main ="Space = 2.0") 
axis(side = 1, at = bp2[at_tick2] , labels = labels2) 
### the lower layer
bp2 <- barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.0, main ="Space = 0.0") 
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 0.5, main ="Space = 0.5") 
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
barplot(df2[,2], xaxt = "n", ylab= "y-axis", space= 2.0, main ="Space = 2.0") 
axis(side = 1, at = bp2[at_tick2] , labels = labels2)
par(mfrow = c(1,1))

看看这里:

  • 顶层:每次重新计算bp
  • 底层:bp space=0重复使用

Illustration of space and bar midpoints info

在控制台中剪切和粘贴命令可能会比上面的图片更好地说明效果。

我希望这会有所帮助。

答案 1 :(得分:0)

您可以使用axis函数,我使用match来获取轴上日期的索引:

space=1
#Plot bars but without x-axis
barplot(df[,2], names.arg=format(index(df), "%Y"), ann=FALSE, bty="n", tck=-0, xaxt="n", 
       col=1:1,  border=NA, space=space); title(main="Example chart", ylab="y-axis")

# Set x-axis parameters
x_min <- min(index(df))
x_max <- max(index(df))

#Add x-axis
axis(1, at=match(seq(as.Date(x_min), x_max, "years"),index(df))*(1+space),
     labels = format(seq(as.Date(x_min), x_max, "years"),"%Y"),lwd=0)

希望这有帮助!

enter image description here