我一直在制作不同的图表集,所有图表都在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引入这个项目。
谢谢!
答案 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 = "")
这产生以下图:
我知道这不是一个条形图,但我不知道这里会添加一个条形图。请告诉我,这是否是你想要的。
如果您确实想使用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)
产生以下情节:
请告诉我,这是否是你想要的。
在解释为什么刻度线和标签在左侧组合在一起时,我们需要考虑两位信息。
(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
重复使用在控制台中剪切和粘贴命令可能会比上面的图片更好地说明效果。
我希望这会有所帮助。
答案 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)
希望这有帮助!