如何填充由直线和曲线创建的几何图形?
How to fill geometric figures created by lines and curves?
我正在尝试用不同的颜色填充下图中的 3 个三角形。
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()
我该怎么做?
简短的回答:这是一个非常邪恶的 hack。
现在让我们详细说明:正如 especially in this GitHub thread 中所讨论的,无法访问 geom_curve
产生的坐标(它使用 CurveGrob
进行绘图,"These values are all calculated at draw time" [ @thomasp85])。它的 'calculation at draw time behaviour' 的一个效果如下所示 - 如果您添加或不添加 coord_plot
会有所不同。这与 geom_spline
不同:添加 coord_fixed
不会更改坐标。
参见下面的第一和第二图:红色曲线是用 geom_curve
创建的 - 它与 geom_segment 失去联系行...
@thomasp85 在 GitHub 线程中建议可以改用他的包 ggforce
。现在,要真正控制曲率,需要使用 geom_bspline 并调整曲率。
一旦找到曲率,就可以使用 ggplot_build 对象中的坐标。我们可以根据这些坐标计算多边形(这也不是很简单,因为需要创建切割并为正确的 'edges' 添加点)。见下文。
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))
接下来我演示'绘制时计算(红色曲线)和'direct calculation':
的区别
和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 (v0.3.0)
于 2019-12-05 创建
您可以访问在 ggforce 包中生成的几何图形的曲线数据,这使得从曲线创建多边形的工作变得更加容易。
然后您可以使用 geom_polygon 绘制单个多边形并用不同的颜色填充它们
library(ggforce)
p1 <- ggplot() + geom_arc(aes(x0 = 125, y0 = -200, r = 100, start = -pi/3, end = -pi/9))
p2 <- ggplot() + geom_arc(aes(x0 = 125, y0 = -200, r = 100, start = -pi/9, end = pi/9))
p3 <- ggplot() + geom_arc(aes(x0 = 125, y0 = -200, r = 100, start = pi/9, end = pi/3))
df_poly1 <- rbind(c(125,-200),data.frame(x = ggplot_build(p1)$data[[1]]$x,y = ggplot_build(p1)$data[[1]]$y),c(125,-200))
df_poly2 <- rbind(c(125,-200),data.frame(x = ggplot_build(p2)$data[[1]]$x,y = ggplot_build(p2)$data[[1]]$y),c(125,-200))
df_poly3 <- rbind(c(125,-200),data.frame(x = ggplot_build(p3)$data[[1]]$x,y = ggplot_build(p3)$data[[1]]$y),c(125,-200))
ggplot() +
geom_polygon(data = df_poly1, aes(x,y), fill = 'red') +
geom_polygon(data = df_poly2, aes(x,y), fill = 'blue') +
geom_polygon(data = df_poly3, aes(x,y), fill = 'green')
这将产生这样的图像。
我正在尝试用不同的颜色填充下图中的 3 个三角形。
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()
我该怎么做?
简短的回答:这是一个非常邪恶的 hack。
现在让我们详细说明:正如 especially in this GitHub thread 中所讨论的,无法访问 geom_curve
产生的坐标(它使用 CurveGrob
进行绘图,"These values are all calculated at draw time" [ @thomasp85])。它的 'calculation at draw time behaviour' 的一个效果如下所示 - 如果您添加或不添加 coord_plot
会有所不同。这与 geom_spline
不同:添加 coord_fixed
不会更改坐标。
参见下面的第一和第二图:红色曲线是用 geom_curve
创建的 - 它与 geom_segment 失去联系行...
@thomasp85 在 GitHub 线程中建议可以改用他的包 ggforce
。现在,要真正控制曲率,需要使用 geom_bspline 并调整曲率。
一旦找到曲率,就可以使用 ggplot_build 对象中的坐标。我们可以根据这些坐标计算多边形(这也不是很简单,因为需要创建切割并为正确的 'edges' 添加点)。见下文。
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))
接下来我演示'绘制时计算(红色曲线)和'direct calculation':
的区别和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 (v0.3.0)
于 2019-12-05 创建您可以访问在 ggforce 包中生成的几何图形的曲线数据,这使得从曲线创建多边形的工作变得更加容易。
然后您可以使用 geom_polygon 绘制单个多边形并用不同的颜色填充它们
library(ggforce)
p1 <- ggplot() + geom_arc(aes(x0 = 125, y0 = -200, r = 100, start = -pi/3, end = -pi/9))
p2 <- ggplot() + geom_arc(aes(x0 = 125, y0 = -200, r = 100, start = -pi/9, end = pi/9))
p3 <- ggplot() + geom_arc(aes(x0 = 125, y0 = -200, r = 100, start = pi/9, end = pi/3))
df_poly1 <- rbind(c(125,-200),data.frame(x = ggplot_build(p1)$data[[1]]$x,y = ggplot_build(p1)$data[[1]]$y),c(125,-200))
df_poly2 <- rbind(c(125,-200),data.frame(x = ggplot_build(p2)$data[[1]]$x,y = ggplot_build(p2)$data[[1]]$y),c(125,-200))
df_poly3 <- rbind(c(125,-200),data.frame(x = ggplot_build(p3)$data[[1]]$x,y = ggplot_build(p3)$data[[1]]$y),c(125,-200))
ggplot() +
geom_polygon(data = df_poly1, aes(x,y), fill = 'red') +
geom_polygon(data = df_poly2, aes(x,y), fill = 'blue') +
geom_polygon(data = df_poly3, aes(x,y), fill = 'green')
这将产生这样的图像。