基于ggplot的空气质量分析:绘图报错及图表优化需求
空气污染分析代码问题解决
问题背景
使用以下R代码做空气污染分析时,第一个散点图正常显示,但第二、第三个柱状图报错Error: Discrete value supplied to continuous scale。尝试用as.factor和as.numeric转换变量未解决问题,同时希望第三个图改用第一个图的绿红渐变配色。
原代码:
Acri$Data <- as.POSIXct(Acri$Data, format = "%m/%d/%Y") Acri$day <- as.numeric(format(Acri$Data, "%d")) Acri$month <- as.numeric(format(Acri$Data, "%m")) Acri$year <- as.numeric(format(Acri$Data, "%Y")) library(waclr) Acri$wd <- cardinal_direction_to_degrees(Acri$wd, north_is = 0) # 第一个图 ggplot(data = Acri, aes(x = PM10, y = ws)) + geom_point(aes(col = NO2)) + theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank()) + scale_color_gradient(low = "green", high = "red") + labs(title = "PM10与风速下NO2的分布", x = "PM10 (μg/m³)", y = "风速 (m/s)") # 第二个图 ggplot(data = Acri, aes(month)) + geom_bar(aes(fill = NO2), width = 0.5) + scale_fill_brewer(palette = "Set2") + theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank()) + theme(axis.title.y = element_blank(), axis.text.y = element_blank()) + scale_x_continuous(breaks = seq(1, 12, 1)) + labs(title = "各月份NO2的分布", x = "月份") # 第三个图 ggplot(data = Acri, aes(season)) + geom_bar(aes(fill = NO2), width = 0.5) + scale_fill_brewer(palette = "Set2") + theme(panel.grid.major=element_blank(),panel.grid.minor=element_blank()) + theme(axis.title.y = element_blank(), axis.ticks.y = element_blank()) + labs(title = "各季节NO2的分布", x = "季节")
尝试过的无效转换:
Acri$NO2 <- as.numeric(levels(Acri$NO2))[Acri$NO2] Acri$PM10 <- as.numeric(levels(Acri$PM10))[Acri$PM10]
示例数据:
Acri <- structure(list(NetC = c("Cosenza Provincia", "Cosenza Provincia", "Cosenza Provincia", "Cosenza Provincia", "Cosenza Provincia", "Cosenza Provincia", "Cosenza Provincia"), ID = c("IT2110A", "IT2110A", "IT2110A", "IT2110A", "IT2110A", "IT2110A", "IT2110A" ), Stat = c("Acri", "Acri", "Acri", "Acri", "Acri", "Acri", "Acri" ), Data = c("1/1/2021", "1/2/2021", "1/3/2021", "1/4/2021", "1/5/2021", "1/6/2021", "1/7/2021"), NO2 = c(27.84, 28.79, 17.76, 24.59, 13.6, 7.34, 25.22), PM10 = c(22, 17.8, 25.3, 18.6, 13.7, 27.6, 34.7), ws = c(1.47, 1.64, 2.52, 1.95, 3.07, 4.4, 1.72), wd = c("SSE", "SSE", "O", "ONO", "ONO", "ONO", "ONO")), class = "data.frame", row.names = c(NA, -7L))
错误原因
- 第二个图中
month是数值型连续变量,geom_bar默认统计计数,与fill=NO2(连续数值)的填充逻辑冲突;同时示例数据中无season变量,需先从月份衍生。 scale_fill_brewer是离散分类配色方案,不能直接用于连续的NO2数值,这是报错的核心原因。
解决方案
步骤1:生成季节变量
从month衍生出季节分类:
# 按1-3春、4-6夏、7-9秋、10-12冬划分季节 Acri$season <- cut(Acri$month, breaks = c(0,3,6,9,12), labels = c("春季","夏季","秋季","冬季"), include.lowest = TRUE)
步骤2:修正第二个图(月份NO2分布)
先按月份聚合NO2均值,再用geom_col直接绘制数值,搭配连续渐变填充:
library(dplyr) library(ggplot2) # 按月份聚合NO2均值 monthly_no2 <- Acri %>% group_by(month) %>% summarise(avg_no2 = mean(NO2, na.rm = TRUE)) # 绘制月份NO2分布图 ggplot(data = monthly_no2, aes(x = factor(month), y = avg_no2)) + geom_col(aes(fill = avg_no2), width = 0.5) + scale_fill_gradient(low = "green", high = "red") + theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank()) + theme(axis.title.y = element_blank(), axis.text.y = element_blank()) + scale_x_discrete(labels = 1:12) + labs(title = "各月份NO2的平均分布", x = "月份")
步骤3:修正第三个图(季节NO2分布,渐变配色)
按季节聚合NO2均值,复用绿红渐变填充:
# 按季节聚合NO2均值 seasonal_no2 <- Acri %>% group_by(season) %>% summarise(avg_no2 = mean(NO2, na.rm = TRUE)) # 绘制季节NO2分布图 ggplot(data = seasonal_no2, aes(x = season, y = avg_no2)) + geom_col(aes(fill = avg_no2), width = 0.5) + scale_fill_gradient(low = "green", high = "red") + theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank()) + theme(axis.title.y = element_blank(), axis.ticks.y = element_blank()) + labs(title = "各季节NO2的平均分布", x = "季节")
关键说明
- 替换
geom_bar为geom_col:前者默认统计计数,后者直接绘制数值,适配NO2的连续数值展示。 - 数据聚合:按月份/季节计算NO2均值,避免单个日期对应一个柱子的混乱展示。
- 配色替换:用
scale_fill_gradient(连续数值配色)替代scale_fill_brewer(离散分类配色),匹配NO2的连续属性。
内容的提问来源于stack exchange,提问作者Elena Iakimova
相关产品推荐
相关产品推荐

