You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:23:14