R语言Plotly极坐标图:线条无法按年份渐变着色问题
问题描述
尝试用R的Plotly绘制极坐标图,希望线条颜色随观测年份(year)呈现渐变效果(例如90年的月度数据,年份推进时线条颜色沿渐变过渡)。但目前图例显示渐变范围,线条却完全不匹配,还出现报错:line.color doesn't (yet) support data arrays。
用户运行代码:
gsod_temp %>% filter(ctry == 'AU') %>% arrange(date) %>% plot_ly(type = 'scatterpolar', mode = 'lines') %>% add_trace(r = ~avg_temp, theta = ~(360*(mo_num/12)), color = ~year )
数据框结构:
tibble [168,912 × 10] (S3: tbl_df/tbl/data.frame) $ ...1 : num [1:168912] 19 45 46 47 83 84 85 86 87 140 ... $ ctry : chr [1:168912] "RU" "DE" "GB" "IE" ... $ year : num [1:168912] 1931 1932 1932 1932 1933 ... $ mo : chr [1:168912] "01" "01" "01" "01" ... $ avg_temp : num [1:168912] 28.6 37 45 47.4 41.9 ... $ Name : chr [1:168912] "Russian Federation" "Germany" "United Kingdom" "Ireland" ... $ year_mo : num [1:168912] 193101 193201 193201 193201 193301 ... $ mo_num : num [1:168912] 1 1 1 1 1 1 1 1 1 1 ... $ date : Date[1:168912], format: "1931-01-01" "1932-01-01" ... $ mo_factor: Ord.factor w/ 12 levels "01"<"02"<"03"<..: 1 1 1 1 1 1 1 1 1 1 ...
示例数据:
> head(gsod_temp) # A tibble: 6 × 10 ...1 ctry year mo avg_temp Name year_mo mo_num date mo_factor <dbl> <chr> <dbl> <chr> <dbl> <chr> <dbl> <dbl> <date> <ord> 1 19 RU 1931 01 28.6 Russian Federa… 193101 1 1931-01-01 01 2 45 DE 1932 01 37.0 Germany 193201 1 1932-01-01 01 3 46 GB 1932 01 45.0 United Kingdom 193201 1 1932-01-01 01 4 47 IE 1932 01 47.4 Ireland 193201 1 1932-01-01 01 5 83 IE 1933 01 41.9 Ireland 193301 1 1933-01-01 01 6 84 KZ 1933 01 0.517 Kazakhstan 193301 1 1933-01-01 01
测试数据集代码:
gsod_temp <- data.frame( ctry = "AU", year = c(2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2023,2021,2022,2021,2022 ), avg_temp = c(73.7015450651341,75.4104290076383,73.6868657848023,72.2521273258409,73.1598298903227,73.4616700246468,70.1546055016525,71.9082260213444,71.2348908276238,65.3337760102265,67.2879372517948,65.4183841482946,60.3262843120212,61.1217217232473,58.5109055884243,56.5089054849122,55.9951720218307,56.9544276966095,55.8852550612849,54.0446941350753,56.258190531307,57.8043905662884,57.1572954432571,58.4890723197841,61.1094747395333,60.643525057218,63.5242135946568,64.9447142925673,64.809677957349,65.1997852147852,67.7951035968358,66.7495405578443,72.3003820409705,70.6337899227766 ), mo_num = c(1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,12,12 ), date = c("2021-01-01","2022-01-01","2023-01-01","2021-02-01","2022-02-01","2023-02-01","2021-03-01","2022-03-01","2023-03-01","2021-04-01","2022-04-01","2023-04-01","2021-05-01","2022-05-01","2023-05-01","2021-06-01","2022-06-01","2023-06-01","2021-07-01","2022-07-01","2023-07-01","2021-08-01","2022-08-01","2023-08-01","2021-09-01","2022-09-01","2023-09-01","2021-10-01","2022-10-01","2023-10-01","2021-11-01","2022-11-01","2021-12-01","2022-12-01" ) ) gsod_temp %<>% mutate(date = ymd(date))
用户尝试将year转为因子,得到的是每年对应一种离散颜色,不符合渐变需求。
问题原因与解决方法
错误原因
Plotly的scatterpolar类型中,单条折线不支持用数组直接设置渐变颜色——报错信息已经明确说明line.color暂不支持数据数组。你的代码将所有年份的数据放在同一条折线里,试图用color=~year给折线的不同段赋不同颜色,这违背了Plotly当前的API限制。
另外,直接用连续型year映射颜色时,Plotly会默认按连续色阶处理,但单条折线无法分段着色,所以出现图例和线条不匹配的问题;转成因子则变成离散颜色,也不符合渐变需求。
解决思路
要实现年份渐变的折线效果,需要按年份分组,每年绘制一条独立的折线,然后将年份作为连续变量映射到颜色标尺,让不同年份的折线颜色沿色阶渐变。
修正后的代码
library(plotly) library(dplyr) library(lubridate) # 先按年份分组,确保每年的数据是完整的月度序列 au_data <- gsod_temp %>% filter(ctry == 'AU') %>% arrange(year, mo_num) %>% group_by(year) %>% # 可选:确保每个年份有12个月的数据,避免折线中断 complete(mo_num = 1:12, fill = list(avg_temp = NA)) %>% ungroup() # 绘制极坐标图,按年份添加折线 plot_ly(type = 'scatterpolar', mode = 'lines') %>% lapply(unique(au_data$year), function(y) { year_data <- filter(au_data, year == y) add_trace( x = ., r = ~avg_temp, theta = ~(360*(mo_num/12)), name = as.character(y), # 用年份映射连续色阶 color = I(colorRampPalette(c("#1f77b4", "#ff7f0e"))(length(unique(au_data$year)))[which(unique(au_data$year) == y)]), showlegend = TRUE ) }) %>% # 设置颜色标尺,对应年份范围 colorbar(title = "年份", limits = range(au_data$year)) %>% layout( polar = list( radialaxis = list(title = "平均温度"), angularaxis = list( tickmode = "array", tickvals = seq(0, 330, 30), ticktext = c("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月") ) ) )
关键说明
- 分组绘制折线:每个年份对应一条独立折线,这样每条折线可以分配单一颜色,通过色阶让年份从早到晚颜色渐变。
- 连续色阶映射:用
colorRampPalette生成对应年份数量的渐变颜色,按年份顺序分配给每条折线。 - 完整数据处理:用
complete确保每个年份有12个月的数据,避免折线因缺失月份中断。 - 自定义角度刻度:将极坐标的角度刻度替换为月份名称,提升可读性。
备选方案(单条线内渐变)
如果希望折线的单条线内按年份渐变(比如跨年度的折线分段变色),目前Plotly的scatterpolar暂不支持这种操作,可以考虑用ggplot2结合极坐标功能实现:
library(ggplot2) au_data %>% mutate(year_norm = (year - min(year))/(max(year)-min(year))) %>% # 归一化年份用于颜色映射 ggplot(aes(x = mo_num, y = avg_temp, color = year_norm)) + geom_line() + scale_color_gradient(low = "#1f77b4", high = "#ff7f0e", labels = unique(au_data$year)) + coord_polar(start = -pi/12) + # 调整极坐标起始角度对应1月 scale_x_continuous(breaks = 1:12, labels = c("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月")) + labs(color = "年份", y = "平均温度") + theme_minimal()
内容的提问来源于stack exchange,提问作者Lachlan Macnish
相关产品推荐
相关产品推荐

