r - 如何在R中的geom_segment/ggplot2中绘制定向蜘蛛网络?

标签 r ggplot2

我正在努力绘制所谓的spider networkdesire line它说明了事物(人、车辆等)在特定区域之间按方向的移动。

这是我正在使用的数据框:

df <- data.frame(O=c(1,2,4,4,4,6,6,6,7,7,7,9,9,9,9,10,10,10,11,12,12,12,32,86,108,128,128,157,157,157,157,157),
D=c(2,1,6,7,32,4,7,157,4,6,157,10,11,12,157,9,12,157,9,9,10,157,4,128,128,86,108,6,7,9,10,12),
trip=c(971,971,416,621,330,416,620,1134,621,620,625,675,675,378,439,675,724,472,675,378,724,563,330,610,405,610,405,1134,625,439,472,563),
lon.x=c(697746.6,696929.6,696748.8,696748.8,696748.8,694906.4,694906.4,694906.4,696769.4,696769.4,696769.4,698802.2,698802.2,698802.2,698802.2,698900.5,698900.5,698900.5,699686.7,696822.0,696822.0,696822.0,698250.7,702314.7,700907.1,702839.5,702839.5,694518.9,694518.9,694518.9,694518.9,694518.9),
lat.x=c(9312405,9311051,9308338,9308338,9308338,9307087,9307087,9307087,9305947,9305947,9305947,9304338,9304338,9304338,9304338,9302314,9302314,9302314,9306300,9303080,9303080,9303080,9309423,9320738,9321302,9322619,9322619,9301921,9301921,9301921,9301921,9301921),
lon.y=c(696929.6,697746.6,694906.4,696769.4,698250.7,696748.8,696769.4,694518.9,696748.8,694906.4,694518.9,698900.5,699686.7,696822.0,694518.9,698802.2,696822.0,694518.9,698802.2,698802.2,698900.5,694518.9,696748.8,702839.5,702839.5,702314.7,700907.1,694906.4,696769.4,698802.2,698900.5,696822.0),
lat.y=c(9311051,9312405,9307087,9305947,9309423,9308338,9305947,9301921,9308338,9307087,9301921,9302314,9306300,9303080,9301921,9304338,9303080,9301921,9304338,9304338,9302314,9301921,9308338,9322619,9322619,9320738,9321302,9307087,9305947,9304338,9302314,9303080))
df包含以下字段:O : 旅行的起源D : 旅行目的地trip :O之间的行程次数和 Dlon.x : 原点经度lat.x : 原点纬度lon.y : 目的地区域的经度lat.y : 目的地区域的纬度

目前我可以使用 geom_segment 通过这里的脚本绘制下图在 ggplot2包裹:
library(ggplot2)

ggplot() +
  geom_segment(data = df, aes(x = lon.x, y = lat.x, xend = lon.y, yend = lat.y, size = trip),
               color = "blue", alpha = 0.5, show.legend = TRUE,
               position = position_dodge2(width = 100)) +
 scale_size_continuous(range = c(0, 5), breaks = c(300, 600, 900, 1200),
                       limits = c(100, 1200), name = "Person trips/day (over 100 trips)") +
 theme(legend.key = element_rect(colour = "transparent", fill = alpha("black", 0))) + 
 guides(size = guide_legend(override.aes = list(alpha = 1.0))) +
 geom_point(data = df, aes(x = lon.x, y = lat.x), pch = 16, size = 2.4)

enter image description here

问题是来自 O 的每一行至 D来自 DO是重叠的。我更喜欢绘制基于中心线躲避的线段,以正确可视化总行程数并查看区域对之间的行程平衡。

所需结果的示例如下所示。

虚线中心线不一定显示(我只是用它来显示平衡是什么)。也最好按方向改变颜色,例如顺时针方向为红色,逆时针方向为蓝色。如果方向可以用颜色显示,则不需要箭头。

enter image description here

我找到了一些例子来解决这个问题,但是目前我无法达到理想的结果。

坐标偏移计算
在这个例子中,为每个方向设置偏移并不是那么容易,因为我有大约 80 个区域,结果是 6,400 对区域。
Offset geom_segment in ggplot

position_dodge2 函数
它说我可以在 width 中设置段之间的边距使用变量,但是如果我使用 trip在其中,它返回错误。此外,不清楚我应该为适当的偏移设置多少值以使线段遵循中心线。
https://ggplot2.tidyverse.org/reference/position_dodge.html

geom_curvearrow
也可以用曲线画线来解决上述问题。然而,曲线段很难观察一个图中的运动。箭头也有点难以看清方向,因为虽然我改变了它的风格,但箭头的形状并不锋利。

color=variableposition=dodge
我也试过spread/gather df获取新变量 direction并删除相反方向的 OD 对,以便我认为我可以使用 color=direction 轻松躲避线段和 position=dodgeggplot2 ,但是效果不佳(段仍然重叠)。小例子如下所示。
O   D trip  direction    lon.x   lat.x    lon.y   lat.y
1   2  971  clock     697746.6 9312405 696929.6 9311051
2   1  300  anticlock 696929.6 9311051 697746.6 9312405
4   6  416  clock     696748.8 9308338 694906.4 9307087
4   7  621  anticlock 694906.4 9307087 696748.8 9308338

我非常感谢您获得精心设计的身材的想法。
另请参见下图以获取spider network 的实际使用情况。 .
enter image description here

最佳答案

您可以使用三角函数来计算偏移值,然后将其插入 ggplot()称呼。以下是使用上述数据集的示例。我不太清楚你所说的顺时针是什么意思,所以我输入了一个简单的虚拟变量。

# make a dummy "clockwise" variable for now
df$clockwise = df$O > df$D
# angle from coordinates of stations
df$angle = atan((df$lat.y - df$lat.x)/(df$lon.y - df$lon.x))
# offsets from cos/sin of orthogonal angle
# scale the distance of the offsets by the trip size so wider bars offset more
# offset them one way if the trip is clockwise, the other way if not clockwise
df$xoffset = cos(df$angle - pi/2) * df$trip/5 * (2 * df$clockwise - 1)
df$yoffset = sin(df$angle - pi/2) * df$trip/5 * (2 * df$clockwise - 1)

ggplot() +
  geom_segment(data = df, aes(x = lon.x + xoffset, y = lat.x + yoffset, xend = lon.y + xoffset, yend = lat.y + yoffset, size = trip, color = clockwise),
               alpha = 0.5, show.legend = TRUE) +
  scale_size_continuous(range = c(0, 5), breaks = c(300, 600, 900, 1200),
                        limits = c(100, 1200), name = "Person trips/day (over 100 trips)") +
  theme(legend.key = element_rect(colour = "transparent", fill = alpha("black", 0))) + 
  guides(size = guide_legend(override.aes = list(alpha = 1.0))) +
  geom_point(data = df, aes(x = lon.x, y = lat.x), pch = 16, size = 2.4) +
  coord_fixed()

Sample plot with above code

关于r - 如何在R中的geom_segment/ggplot2中绘制定向蜘蛛网络?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51300440/

相关文章:

r - 如何编写将输出作为 S3 类返回的函数

r - 如何在不使用 axis 命令的情况下直接在右侧绘制 y 轴?

r - 将多个文本注释添加到多面 ggplot geom_histogram

r - 有没有办法去除用 geom_sf_text 制作的标签周围的边框?

r - ggplot2:向网格添加对角线

regex - R/regex with stringi/ICU : why is a '+' considered a non-[:punct:] character?

r - mutate_at 有两组变量

r - 计算字符串向量中连续数字的函数

r - 如何在不禁用 geom_smooth 的情况下构建悬停文本?

r - ggplot2 图表轴中的印度风格千位分隔符