如何在R中实现带-0.05至0.05连续刻度的趋势空间点图?
问题概述
想要用R的ggplot2绘制趋势空间点图,要求:
- 用
Sen变量控制点的大小:数值绝对值越大,点越大 - 颜色区分正负:负值为蓝色,正值为红色
- 图例呈现连续刻度:范围从-0.05到0.05,步长0.01(共11个刻度点,5个蓝色负值、1个中点、5个红色正值)
原代码将颜色设为分类变量,仅能展示"负值/正值"两个类别,无法实现连续刻度的需求。
原代码如下:
library(ggplot2) #Creating a funtion for the point size point_size <- function(x) { ifelse(x >= 0, 0.05 + x * 0.01, 0.05 - x * 0.01) } #Creating a funtion for color color <- function(x) { ifelse(x >= 0, "red", "blue") } #Data data <- data.frame(Z = c(2.7, 1.8, 2.1, 1.4, -1.9, -2.3), Sen = c(0.03, -0.03, 0.01, -0.015, 0.025, -0.05), lon = c(-70.123, -71.456, -69.789, -72.012, -73.345, -68.901), lat = c(-33.456, -32.012, -34.345, -31.678, -33.901, -35.234)) #Adjusting the size of the points data$size <- point_size(data$Sen) #Adjusting the color of the points data$color <- color(data$Sen) #Creating the dotmap with filled circles and black border map_point <- ggplot(data, aes(x = lon, y = lat, size = size, fill = color)) + geom_point(shape = 21, color = "black") + scale_size_continuous(range = c(2, 8)) + labs(title = "Map of points", x = "Longitude", y = "Latitude", size = "Size", fill = "Value") + theme_minimal() + scale_fill_manual(values = c("blue" = "blue", "red" = "red"), labels = c("Negatives", "Positives")) print(mapa_puntos) # 此处变量名错误,应为map_point
解决方案
可以通过以下修改实现连续刻度的图例,同时保留点大小和颜色的需求:
关键修改点:
- 直接将
Sen变量映射到fill和size,无需提前生成分类的color列和计算后的size列 - 使用
scale_fill_gradient2实现正负值的颜色区分(蓝色负值、红色正值,中点为0) - 用
abs(Sen)控制点大小,保证正负值的绝对值越大,点越大,匹配原需求逻辑 - 设置连续图例的刻度范围和步长,统一图例标题
修改后的完整代码:
library(ggplot2) # 原始数据 data <- data.frame( Z = c(2.7, 1.8, 2.1, 1.4, -1.9, -2.3), Sen = c(0.03, -0.03, 0.01, -0.015, 0.025, -0.05), lon = c(-70.123, -71.456, -69.789, -72.012, -73.345, -68.901), lat = c(-33.456, -32.012, -34.345, -31.678, -33.901, -35.234) ) # 绘制空间点图 map_point <- ggplot(data, aes(x = lon, y = lat)) + # 直接映射Sen到fill,用abs(Sen)控制点大小 geom_point(aes(fill = Sen, size = abs(Sen)), shape = 21, color = "black") + # 颜色渐变:负值蓝色,正值红色,中点为0 scale_fill_gradient2( low = "blue", high = "red", mid = "white", # 0值的颜色,可根据需求调整或删除 midpoint = 0, breaks = seq(-0.05, 0.05, 0.01), # 设置连续刻度步长 limits = c(-0.05, 0.05), # 限定图例范围 name = "Sen Value" # 统一图例标题 ) + # 点大小映射:根据abs(Sen)调整显示范围 scale_size_continuous( range = c(2, 8), breaks = seq(0, 0.05, 0.01), # 大小刻度与Sen绝对值对应 limits = c(0, 0.05), name = "Sen Value" ) + # 合并size和fill的图例,让视觉呈现更统一 guides( size = guide_legend(order = 1), fill = guide_colorbar(order = 1, title.position = "top") ) + labs( title = "Trend Spatial Dot Map", x = "Longitude", y = "Latitude" ) + theme_minimal() # 输出图形 print(map_point)
代码说明:
scale_fill_gradient2是实现连续颜色渐变的核心函数,通过midpoint=0区分正负颜色,breaks参数指定了从-0.05到0.05、步长0.01的刻度- 点大小用
abs(Sen)映射,保证正负值的绝对值越大,点越大,和原代码的point_size函数逻辑一致 - 通过
guides可以将size和fill的图例合并,避免重复图例干扰 - 如果不需要0值的白色,可删除
mid = "white"参数,此时0值会呈现蓝红之间的过渡色
内容的提问来源于stack exchange,提问作者Yil
相关产品推荐
相关产品推荐

