如何用ggplot2绘制Habitat分色系、SVI渐变的郡级Acres柱状图
解决方案:分类+连续变量的配色调整
你的代码问题在于错误地将填充色(fill)映射为离散的栖息地类型(Habitat),而把边框色(color)映射为连续的SVI值,这和你想要的「填充色随SVI渐变、且不同栖息地用不同色系」的需求不符。以下是两种可行的改进方案:
方法一:预先生成对应颜色列(无需额外包)
利用数据中每个郡的两类栖息地SVI值相同的特点,提前为每个数据点生成匹配的渐变颜色,再用scale_fill_identity映射:
library(ggplot2) library(scales) # 定义粉色(海草)和蓝色(盐沼)的渐变范围 pink_gradient <- gradient_n_pal(c("#FFE6E6", "#FF3366"), values = rescale(range(df$SVI))) blue_gradient <- gradient_n_pal(c("#E6F2FF", "#3366FF"), values = rescale(range(df$SVI))) # 为每行数据分配对应颜色 df$fill_color <- ifelse(df$Habitat == "Seagrass", pink_gradient(df$SVI), blue_gradient(df$SVI)) # 绘制柱状图 ggplot(df, aes(x = County, y = Acres, fill = fill_color)) + geom_bar(stat = "identity", position = position_dodge(width = 0.9)) + # 用identity映射预定义颜色,手动设置图例 scale_fill_identity(guide = "legend", labels = c( paste("海草 (SVI:", round(df$SVI[df$Habitat=="Seagrass"],4), ")"), paste("盐沼 (SVI:", round(df$SVI[df$Habitat=="Saltmarsh"],4), ")") ), breaks = df$fill_color) + labs(x = "郡", y = "面积(英亩)", fill = "栖息地与SVI") + theme(axis.text.x = element_text(angle = 45, hjust = 1))
方法二:用ggnewscale实现独立渐变图例(更直观)
如果希望为海草和盐沼分别展示SVI渐变图例,可以使用ggnewscale包添加独立的填充色比例尺:
library(ggplot2) library(ggnewscale) ggplot() + # 先绘制海草柱形,粉色渐变 geom_bar(data = df[df$Habitat == "Seagrass", ], aes(x = County, y = Acres, fill = SVI), stat = "identity", position = position_dodge(width = 0.9)) + scale_fill_gradient(low = "#FFE6E6", high = "#FF3366", name = "海草SVI") + # 添加新的填充色比例尺,不与前面冲突 new_scale_fill() + # 再绘制盐沼柱形,蓝色渐变 geom_bar(data = df[df$Habitat == "Saltmarsh", ], aes(x = County, y = Acres, fill = SVI), stat = "identity", position = position_dodge(width = 0.9)) + scale_fill_gradient(low = "#E6F2FF", high = "#3366FF", name = "盐沼SVI") + labs(x = "郡", y = "面积(英亩)") + theme(axis.text.x = element_text(angle = 45, hjust = 1))
内容的提问来源于stack exchange,提问作者Annick
相关产品推荐
相关产品推荐

