r - 如何填充由直线和曲线创建的几何图形?

标签 r ggplot2 fill

我正在尝试用不同的颜色填充下图中的 3 个三角形。

This is the graphic

data = data.frame(x=c(125), y=c(220)) #this data is just to be able to use gplot to draw figures

ggplot(data, aes(x = x, y = y)) + 
  xlim(0,250) +
  ylim(-250, 0) +
  geom_curve(x = 33, xend = 223, y = -100, yend = -100, curvature = -.65) +
  geom_segment(x=128, xend = 33, y=-208, yend = -100) +
  geom_segment(x=128, xend = 223, y=-208, yend = -100) +
  geom_segment(x=128, xend = 159.67, y=-208, yend = -45) +
  geom_segment(x=128, xend = 96.33, y=-208, yend = -45) +
  coord_fixed()

我该怎么做?

最佳答案

简短的回答:这是一个非常邪恶的黑客行为。

现在让我们详细说明一下:如 especially in this GitHub thread 中所述,无法访问由 geom_curve 生成的坐标(它使用 CurveGrob 进行绘图,并且“这些值都是在绘制时计算的”[@thomasp85])。其“绘制时计算行为”的一个效果如下所示 - 如果您添加或不添加 coord_plot,它会产生影响。这与geom_spline不同:添加coord_fixed不会改变坐标。

请参见下面的图一和图二:红色曲线是使用 geom_curve 创建的 - 它与 geom_segment 线失去了联系...

@thomasp85 在 GitHub 线程中建议可以使用他的包 ggforce 来代替。现在,要真正控制曲率,需要使用 geom_bspline 并调整曲率。

一旦找到曲率,就可以使用 ggplot_build 对象中的坐标。我们可以根据这些坐标计算多边形(这也不是很简单,因为需要创建切割并为正确的“边缘”添加点)。见下文。

library(tidyverse)
library(ggforce)

mydata = data.frame(x = 128, xend = c(33, 223, 159.67, 96.33), y = -208, yend = c(-100,-100,-45,-45))

#for spline control points.
my_spline <- data.frame(x = c(33, 128, 223), y = c(-100, 24,-100))

接下来我演示“绘制时计算(红色曲线)”和“直接计算”之间的区别:

使用coord_fixed 红色和黑色曲线都接触线段

ggplot(mydata) + 
  geom_curve(aes(x = 33, xend = 223, y = -100, yend = -100), curvature = -.65, color = 'red') +
  geom_segment(aes(x = x, xend = xend, y = y, yend = yend)) +
  geom_bspline(data = my_spline, aes(x, y )) +
  coord_fixed()

没有coord_fixed 红色曲线不接触线段,但黑色曲线仍然接触

ggplot(mydata) + 
  geom_curve(aes(x = 33, xend = 223, y = -100, yend = -100), curvature = -.65, color = 'red') +
  geom_segment(aes(x = x, xend = xend, y = y, yend = yend)) +
  geom_bspline(data = my_spline, aes(x, y )) 

# Final hack
# Get x/y coordinates from ggplot_build
p <- ggplot(mydata) + 
  geom_bspline(data = my_spline, aes(x, y )) 

pb <- ggplot_build(p)$data[[1]]

#create groups for fill
data_polygon <- data.frame(x = pb[['x']], y = pb[['y']]) %>% 
  mutate(cut_poly = cut(x, c(-Inf, 96.33, 159.67, Inf), labels = letters[1:3])) 

#add corner points - repeat extremes from b, otherwise there will be a gap
data_add <- data_polygon %>% 
  filter(cut_poly == 'b') %>% 
  slice(which.min(x), which.max(x)) %>% 
  mutate(cut_poly = letters[c(1,3)]) %>%
  bind_rows(data.frame(x = 128, y = -208, cut_poly = letters[1:3], stringsAsFactors = FALSE)) %>% 
  arrange(x) #important to arrange, otherwise you get irregular polygons

data_plot <- rbind(data_polygon,data_add)

ggplot(data_plot) +
  geom_polygon(aes(x, y, fill = cut_poly), color = 'black')

reprex package于2019年12月5日创建(v0.3.0)

关于r - 如何填充由直线和曲线创建的几何图形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59113375/

相关文章:

r - 比较 Julia 中两个向量的元素是否相等

r - 使图例不可见,但保持图形尺寸和边距相同

r - 如何呈现具有多种条件的数据

r - 分面 STRIP 背景中的多种颜色

HTML5/CSS3 如何扩展 anchor 元素以适应其父级的全尺寸

r - R中计算大矩阵逆的最快方法

r - 在r中以相同的pdf或png输出textplot和qplot

html - 填补空白

c++ - 在 2D int vector 上使用 std::fill

r - 在r中写出.dat文件