如何用ggplot2实现Sketchy/Painty/RoughJS/Semiotic风格可视化
在R中实现手绘风格(Sketchy/Painty)可视化方案
针对你想要实现类似Semiotic的手绘质感可视化(包括常规图表和 choropleth地图)的需求,这里提供几个稳定且易配置的替代方案,避开ggrough的稳定性问题:
方案1:使用ggpattern创建随机纹理填充
ggpattern是成熟的ggplot2扩展包,支持为图形元素添加各类纹理,通过调整随机参数可模拟手绘的粗糙质感,适配柱状图、地图等多种场景。
示例1:手绘风格柱状图
library(ggplot2) library(ggpattern) # 模拟数据 df <- data.frame( category = c("A", "B", "C", "D"), value = c(30, 50, 25, 40) ) ggplot(df, aes(x = category, y = value)) + geom_col_pattern( aes(pattern_fill = category), pattern = "stripe", pattern_angle = sample(0:180, nrow(df), replace = TRUE), # 随机条纹角度 pattern_density = runif(nrow(df), 0.1, 0.3), # 随机条纹密度 pattern_spacing = runif(nrow(df), 0.05, 0.15), # 随机条纹间距 color = "black", size = 0.8, fill = NA ) + theme_minimal() + labs(title = "手绘风格柱状图")
示例2:手绘风格 choropleth地图
library(sf) library(ggplot2) library(ggpattern) # 加载内置美国州地图数据 data("states", package = "spData") ggplot(states) + geom_sf_pattern( aes(pattern_fill = total_pop_15), pattern = "circle", pattern_size = runif(nrow(states), 0.1, 0.5), # 随机圆点大小 pattern_density = runif(nrow(states), 0.05, 0.2), # 随机圆点密度 color = "black", size = 0.5 ) + scale_pattern_fill_viridis_c() + theme_minimal() + labs(title = "手绘风格人口密度地图")
方案2:自定义ggplot2几何对象实现随机扰动
通过直接操作grid绘图系统,为图形元素的顶点添加随机偏移,模拟手绘时的抖动效果,适合需要高度自定义的场景。
示例:手绘风格多边形(适配地图)
library(ggplot2) library(sf) library(grid) # 自定义手绘多边形函数 geom_sketch_sf <- function(mapping = NULL, data = NULL, ..., jitter_amount = 0.01) { layer( data = data, mapping = mapping, stat = "identity", geom = GeomSketchSf, position = "identity", params = list(jitter_amount = jitter_amount, ...) ) } GeomSketchSf <- ggproto("GeomSketchSf", GeomSf, draw_panel = function(data, panel_params, coord, jitter_amount = 0.01) { # 对每个多边形顶点添加随机抖动 data$geometry <- lapply(data$geometry, function(sf_geom) { coords <- st_coordinates(sf_geom) coords[,1] <- coords[,1] + rnorm(nrow(coords), 0, jitter_amount) coords[,2] <- coords[,2] + rnorm(nrow(coords), 0, jitter_amount) st_polygon(list(coords)) }) # 调用原生GeomSf的绘制逻辑 GeomSf$draw_panel(data, panel_params, coord) } ) # 使用自定义geom绘制地图 data("states", package = "spData") ggplot(states) + geom_sketch_sf(aes(fill = total_pop_15), jitter_amount = 0.05, color = "black") + scale_fill_viridis_c() + theme_minimal() + labs(title = "抖动手绘风格地图")
方案3:结合RoughJS实现Web端手绘可视化
如果可以接受将可视化导出为网页,利用htmlwidgets调用成熟的RoughJS库,能实现高度还原的手绘效果,稳定性极强。
示例:RoughJS风格地图
library(sf) library(roughsf) data("states", package = "spData") # 转换为适合roughsf的格式 states_sf <- st_transform(states, crs = 4326) # 生成手绘风格地图网页 roughsf( states_sf, fill = states$total_pop_15, fillStyle = "hachure", hachureAngle = sample(0:90, nrow(states_sf), replace = TRUE), hachureGap = runif(nrow(states_sf), 2, 5), strokeWidth = 1 )
以上方案均无需复杂额外配置,稳定性优于ggrough,可根据具体场景选择合适的实现方式。
内容的提问来源于stack exchange,提问作者bill999
相关产品推荐
相关产品推荐

