R语言绘制月度气温3D图展示年月维度气温趋势实现方法咨询
R语言同画布绘制多层3D月度气温分布图实现方法
核心思路是用分层透明度控制避免3D图常见的元素遮挡、信息杂乱问题,同时保留原始观测分布和长期变化趋势,坐标轴严格按需求设置:x轴为月份、y轴为年份、z轴为逐小时气温观测值。
前置依赖与数据预处理
先安装并加载用到的包,把数据整理成绘图需要的格式,注意提前把你用到的气温数据集存到本地R工作目录,不要直接读取在线链接避免读取失败。
# 首次运行先安装缺失包 # install.packages(c("readxl", "plotly", "data.table", "dplyr", "reshape2")) library(readxl) library(plotly) library(data.table) library(dplyr) library(reshape2) # 读取本地气温数据,替换成你本地的文件名即可 dt <- read_excel("temp_data.xlsx") |> as.data.table() # 校验数据需包含三个核心字段:month(1-12数值型)、year(数值型)、hour_temp(逐小时气温数值型) # 提前聚合计算分位数,作为分层绘制的基准:避免全量逐小时数据糊成一团 dt_agg <- dt[, .( q10 = quantile(hour_temp, 0.1, na.rm = T), # 10%分位低温边界 q50 = quantile(hour_temp, 0.5, na.rm = T), # 中位气温,核心趋势层 q90 = quantile(hour_temp, 0.9, na.rm = T) # 90%分位高温边界 ), by = .(month, year)]
多层3D图绘制代码
分层逻辑从下到上依次排布,通过透明度差突出核心趋势:
- 最底层:月份-年份平面的填充等高线,用颜色映射中位气温,作为趋势参考底座
- 上下边界层:10%、90%分位数气温曲面,设置极低透明度,展示逐小时气温的波动区间,不遮挡核心层
- 核心趋势层:中位气温曲面,设置中等透明度,是展示年际、季节气温变化的核心载体
- 最上层:10%抽样的逐小时原始观测散点,小尺寸、低透明度,保留原始数据分布特征
# 生成宽表格式适配3D曲面入参 z_q10 <- acast(dt_agg, year ~ month, value.var = "q10") z_q50 <- acast(dt_agg, year ~ month, value.var = "q50") z_q90 <- acast(dt_agg, year ~ month, value.var = "q90") x_axis <- sort(unique(dt_agg$month)) y_axis <- sort(unique(dt_agg$year)) plot_ly() |> # 1. 底层平面等高线 add_contour( data = dt_agg, x = ~month, y = ~year, z = ~q50, colors = "YlOrRd", showscale = F, contours = list(showlabels = T, labelfont = list(size = 10)) ) |> # 2. 低温边界层 add_surface( x = x_axis, y = y_axis, z = z_q10, opacity = 0.15, colorscale = list(c(0,1), c("#c6dbef", "#c6dbef")), showscale = F, name = "10%分位低温边界", hoverinfo = "name" ) |> # 3. 核心中位气温趋势层 add_surface( x = x_axis, y = y_axis, z = z_q50, opacity = 0.6, colors = "YlOrRd", colorbar = list(title = "中位气温(℃)"), name = "中位气温趋势" ) |> # 4. 高温边界层 add_surface( x = x_axis, y = y_axis, z = z_q90, opacity = 0.15, colorscale = list(c(0,1), c("#fcbba1", "#fcbba1")), showscale = F, name = "90%分位高温边界", hoverinfo = "name" ) |> # 5. 抽样原始观测点 add_markers( data = dt[sample(.N, round(.N*0.1))], # 只抽10%样本避免过密 x = ~month, y = ~year, z = ~hour_temp, size = I(2), opacity = 0.25, color = ~hour_temp, colors = "YlOrRd", showlegend = F, hoverinfo = "x+y+z" ) |> # 坐标轴与视角配置 layout( scene = list( xaxis = list(title = "月份", dtick = 1, range = c(1,12)), yaxis = list(title = "年份"), zaxis = list(title = "逐小时气温(℃)"), # 调整视角减少层之间的遮挡 camera = list(eye = list(x = 1.7, y = 1.7, z = 1.1)) ), legend = list(orientation = "h", y = 1) )
效果优化提示
- 如果只需要看长期趋势,可以直接隐藏上下两个分位边界层,只保留等高线底座+中位趋势面+少量散点,趋势会更清晰
- 要突出年际变暖趋势,可以额外叠加一层线性拟合的趋势基准面,和实际中位气温面的高度差就是对应时段的气温变化幅度
- 不要直接绘制全量逐小时气温的3D散点,高密度点会完全糊成色块,无法识别任何趋势规律
内容的提问来源于stack exchange,提问作者Jimin Eom
相关产品推荐
相关产品推荐

