简体   繁体   English

使用chron在ggplot2图表中放置和格式化日期的麻烦

[英]Trouble with placing and formatting dates in ggplot2 graph using chron

I've been trying to add appropriate dates on the x-axis of my graph, but can't figure out how to do it in a sane way. 我一直在尝试在图表的x轴上添加适当的日期,但无法弄清楚如何以理智的方式做到这一点。 What I want is pretty simple: a date at every January 1st in between the minimum and maximum of my data set. 我想要的很简单:每年1月1日我的数据集的最小值和最大值之间的日期。

I don't want to include the month - just '2008' or '2009' or whatever is fine. 我不想包括这个月 - 只是'2008'或'2009'或者其他什么都没关系。 A great example would be this graph: 一个很好的例子是这个图:

example graph 示例图

Except I want the date on every year, rather than every other year. 除了我想要每年的日期,而不是每隔一年。

I can't seem to figure this out. 我似乎无法弄清楚这一点。 My dates are defined as days since 1/1/1970, and I've included a method dateEPOCH_formatter which converts the epoch format to a format using the chron package. 我的日期定义为自dateEPOCH_formatter日以来的天数,我已经包含了一个方法dateEPOCH_formatter ,它将纪元格式转换为使用chron包的格式。 I've figured out how to make a tick mark and date at the origin of the graph and every 365 days thereafter, but that's not quite the same thing. 我已经想出了如何在图表的原点和之后的365天制作刻度线和日期,但这并不完全相同。

Another minor problem is that, mysteriously, the line chron(floor(y), out.format="mon year",origin.=epoch) outputs a graph with axis markers like 'Mar 2008', but changing the line to chron(floor(y), out.format="year",origin.=epoch) doesn't give me a result like '2008' - it just results in the error: 另一个小问题是,神秘地,行chron(floor(y), out.format="mon year",origin.=epoch)输出带有轴标记的图形,如'Mar 2008',但是将行更改为chron(floor(y), out.format="year",origin.=epoch)没有给我一个像'2008'的结果 - 它只会导致错误:

Error in parse.format(format[1]) : unrecognized format year
Calls: print ... as.character.times -> format -> format.dates -> parse.format
Execution halted

Here's my code - thanks for the help. 这是我的代码 - 感谢您的帮助。

library(ggplot2)
library(chron)
argv <- commandArgs(trailingOnly = TRUE)
mydata = read.csv(argv[1])
png(argv[2], height=300, width=470)


timeHMS_formatter <- function(x) {                  # Takes time in seconds from midnight, converts to HH:MM:SS
h <- floor(x/3600)
m <- floor(x %% 60)
s <- round(60*(x %% 1))                         # Round to nearest second
lab <- sprintf('%02d:%02d', h, m, s)        # Format the strings as HH:MM:SS
lab <- gsub('^00:', '', lab)                    # Remove leading 00: if present
lab <- gsub('^0', '', lab)                      # Remove leading 0 if present
}

dateEPOCH_formatter <- function (y){
epoch <- c(month=1,day=1,year=1970)
    chron(floor(y), out.format="mon year",origin.=epoch)
}

p=  ggplot() + 
coord_cartesian(xlim=c(min(mydata$day),max(mydata$day)), ylim=c(0,86400)) +         # displays data from first email through present
scale_color_hue() +
xlab("Date") +
ylab("Time of Day") +
scale_y_continuous(label=timeHMS_formatter, breaks=seq(0, 86400, 14400)) +              # adds tick marks every 4 hours
scale_x_continuous(label=dateEPOCH_formatter, breaks=seq(min(mydata$day), max(mydata$day), 365) ) +
ggtitle("Email Sending Times") +                                                        # adds graph title
theme( legend.position = "none", axis.title.x = element_text(vjust=-0.3)) +
theme_bw() +
layer(
    data=mydata, 
    mapping=aes(x=mydata$day, y=mydata$seconds), 
    stat="identity", 
    stat_params=list(), 
    geom="point", 
    geom_params=list(alpha=5/8, size=2, color="#A9203E"),
    position=position_identity(),
)   

print(p)
dev.off()

I think it will be much easier to use the built in function scale_x_date with date_format and date_breaks from the scales package. 我认为使用内置函数scale_x_datescales包中的date_formatdate_breaks会更容易。 These should work with most date classes in R , such as Date , chron etc 这些应该适用于R大多数date类,例如Datechron

for example 例如

library(ggplot2)
library(chron)
library(scales)

# some example data 
days <- seq(as.Date('01-01-2000', format = '%d-%m-%Y'),
            as.Date('01-01-2010', format = '%d-%m-%Y'), by = 1)

days_chron <- as.chron(days)
mydata <- data.frame(day = days_chron, y = rnorm(length(days)))

# the plot
ggplot(mydata, aes(x=days, y= y)) + geom_point() + 
 scale_x_date(breaks = date_breaks('year'), labels = date_format('%Y'))

在此输入图像描述

To show how intuitive and easy these function are, if you wanted Montth-year labels every 6 months - note that this requires a very wide plot or very small axis labels 为了显示这些功能的直观性和简单性,如果您每6个月需要一个十年标签 - 请注意这需要非常宽的图或非常小的轴标签

ggplot(mydata, aes(x=days, y= y)) + geom_point() +
   scale_x_date(breaks = date_breaks('6 months'), labels = date_format('%b-%Y'))

在此输入图像描述

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

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