如何在R中为向日葵籽产量数据添加多边形以绘制圆形Voronoi图
生成圆形Voronoi图的多边形数据(适配ggplot2)
需求说明
现有各国向日葵籽产量数据框,需生成包含x、y、path、split、group、value列的多边形数据,用于绘制圆形Voronoi图。
步骤实现
1. 加载基础数据与必要包
首先加载数据,并安装、加载所需R包:
# 加载基础数据 df <- data.frame(country = c("Ukraine", "Russia", "Argentina", "China", "Romania", "Other"), prod = c(11.0, 10.6, 3.1, 2.4, 2.1, 15.3)) # 安装并加载包 install.packages(c("deldir", "ggplot2", "dplyr", "sf")) library(deldir) library(ggplot2) library(dplyr) library(sf)
2. 生成初始坐标点
根据产量占比分配极坐标位置,确保点分布在圆形范围内:
# 计算产量占比 df <- df %>% mutate(prop = prod / sum(prod), # 分配角度(从0到2π) angle = cumsum(prop) * 2 * pi - prop * pi, # 设置半径(按占比调整,让产量高的点离圆心稍远) radius = sqrt(prop) * 0.8) %>% # 转换为笛卡尔坐标 mutate(x = radius * cos(angle), y = radius * sin(angle))
3. 生成Voronoi多边形并裁剪到圆形内
使用deldir生成Voronoi多边形,再用sf裁剪到单位圆边界内:
# 生成Voronoi多边形 voronoi <- deldir(df$x, df$y, rw = c(-1, 1, -1, 1)) voronoi_polys <- tile.list(voronoi) # 转换为sf对象 sf_polys <- lapply(seq_along(voronoi_polys), function(i) { poly <- voronoi_polys[[i]] sf_poly <- st_polygon(list(cbind(poly$x, poly$y))) st_sf(geometry = sf_poly, group = df$country[i], value = df$prod[i]) }) %>% bind_rows() # 创建单位圆用于裁剪 circle <- st_polygon(list(cbind(cos(seq(0, 2*pi, length.out = 100)), sin(seq(0, 2*pi, length.out = 100))))) %>% st_sfc() %>% st_sf() # 裁剪Voronoi多边形到圆内 clipped_polys <- st_intersection(sf_polys, circle)
4. 转换为目标格式数据
将裁剪后的多边形转换为包含x、y、path、split、group、value的长格式:
# 提取坐标并整理格式 final_df <- clipped_polys %>% st_coordinates() %>% as.data.frame() %>% rename(x = X, y = Y, path = L1, split = L2) %>% left_join(clipped_polys %>% mutate(path = row_number()) %>% st_drop_geometry(), by = "path") %>% rename(group = group.y, value = value) %>% select(x, y, path, split, group, value) # 查看结果(前6行) head(final_df)
运行后会得到类似示例的输出格式:
x y path split group value 1 0.7254769 0.2990878 1 1 Ukraine 11.0 2 0.6820767 0.3451880 1 2 Ukraine 11.0 3 0.6364057 0.3870474 1 3 Ukraine 11.0 4 0.5888371 0.4241117 1 4 Ukraine 11.0 5 0.5397082 0.4558694 1 5 Ukraine 11.0 6 0.4893241 0.4818575 1 6 Ukraine 11.0
5. 绘制圆形Voronoi图
用ggplot2绘制最终图形:
ggplot(final_df, aes(x = x, y = y, group = group, fill = group)) + geom_polygon(color = "white", size = 0.5) + coord_equal() + theme_void() + labs(fill = "国家")
内容的提问来源于stack exchange,提问作者LDT
相关产品推荐
相关产品推荐

