在R语言Plotly中将X轴儒略日转换为月份的方法
问题与解决方案
问题背景
我有一组每日采集的数据,使用以下Plotly代码绘制三维曲面图:
library(plotly) library(lubridate) library(raster) dates <- seq(ymd('2010-01-01'), ymd('2020-01-01'), by = 'day') dat <- data.frame(Day = yday(dates), Year = year(dates), Val = rnorm(length(dates))) mat <- as.matrix(rasterFromXYZ(dat)) rownames(mat) <- unique(dat$Year) y <- as.numeric(rownames(mat)) plot_ly(z = mat,y = y, type = "surface", colorscale = list(thresholds_colors = seq(0, 1, length = 6), colors = c('gray','blue','skyblue','green','yellow','red')), showscale=TRUE) %>% layout(title = list(text = 'Test Plot',x=0.47, y=0.92), scene=list( yaxis=list(title='Year'), zaxis = list(title = 'Value'), xaxis = list(title = 'Julian day',autorange="reversed"), camera = list(eye = list(x = 1.3, y = 1.3, z = 1.5))))
绘图后X轴显示的是儒略日,我希望将其替换为月份缩写(如'Jan'、'Feb')。最初尝试修改矩阵列名的方式:
colnames(mat) <- month.abb[month(as.Date(0:365,origin='2000-01-01'))] x <- colnames(mat) plot_ly(z = mat, y = y, x = x, ...
这种方法虽能显示月份名称,但会丢失每日数据的分辨率,仅保留每个月的单个值。
可行解决方案
通过自定义X轴刻度的方式,既保留每日数据的分辨率,又将X轴显示为月份缩写,更新后的代码如下:
library(plotly) library(lubridate) library(raster) dates <- seq(ymd('2010-01-01'), ymd('2020-01-01'), by = 'day') dat <- data.frame(Day = yday(dates), Year = year(dates), Val = rnorm(length(dates))) mat <- as.matrix(rasterFromXYZ(dat)) rownames(mat) <- unique(dat$Year) y <- as.numeric(rownames(mat)) # 计算对应月份的刻度位置和文本 curTcks <- round(seq(1, 366, by = 30.5)) pCurT <- parse_date_time(curTcks, orders = "j") %>% month() newTckTxt <- month.abb[pCurT] plot_ly(z = mat, y = y, type = "surface", colorscale = list(thresholds_colors = seq(0, 1, length = 6), colors = c('gray','blue','skyblue','green', 'yellow','red')), showscale=TRUE) %>% layout(title = list(text = 'Test Plot',x=0.47, y=0.92), scene=list( yaxis=list(title='年份'), zaxis = list(title = '数值'), xaxis = list(title = '月份', autorange="reversed", tickvals = curTcks, ticktext = newTckTxt), camera = list(eye = list(x = 1.3, y = 1.3, z = 1.5))))
关键说明
- 核心是不修改原始数据矩阵结构,在
layout的xaxis参数中,用tickvals指定儒略日对应的刻度位置,ticktext设置对应的月份缩写,兼顾数据分辨率和轴标签需求。 - 用
round(seq(1, 366, by = 30.5))近似每个月起始的儒略日位置,通过lubridate将其转换为对应月份,再用month.abb获取月份缩写。
内容的提问来源于stack exchange,提问作者Overtime4728
相关产品推荐
相关产品推荐

