How to draw directional spider network in geom_segment/ggplot2 in R?
我正在尝试绘制所谓的
这是我正在使用的数据框:
1 2 3 4 5 6 7 | 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)) |
目前,我可以在
1 2 3 4 5 6 7 8 9 10 11 | 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) |
问题在于,从
所需结果的示例如下所示。
虚线中心线不一定会显示(我只是为了表明余额是多少而已)。还优选按方向改变颜色,例如,顺时针方向为红色,而逆时针方向为蓝色。如果可以以彩色显示方向,则不需要箭头。
我找到了一些解决该问题的示例,但是目前无法达到理想的结果。
坐标偏移量的计算
在此示例中,为每个方向设置偏移并不是那么容易,因为我有大约80个区域,这导致6400对区域。
ggplot
中的偏移geom_segment
position_dodge2函数
它说我可以使用变量在
https://ggplot2.tidyverse.org/reference/position_dodge.html
也可以绘制带有曲线的线,从而可以解决上述问题。但是,弯曲的段很难观察一个图形中的运动。箭头也很难看清方向,因为即使更改样式,箭头的形状也不清晰。
我还尝试
1 2 3 4 5 | 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 |
我非常感谢您的想法,以获取精心设计的图形。
另请参见下图,以获取
您可以使用trig函数来计算偏移值,然后将其插入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 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() |