我在用极坐标切掉对象的边界时遇到麻烦。我试图用一个包围矩形绘制平均角度,该矩形显示所有测得角度的标准偏差。但是,由于圆坐标的性质,当sd超出极坐标的范围时,我遇到了麻烦,并且很难使其显示出来。我已经读过this similar question,但是由于各种原因,我需要将这些数据保存在极坐标系中,因此我无法成功地将geom_arc_bar
解决方案应用于该问题。
这是数据的子集:
test <- structure(
list(group = structure(1:4, .Label = c("1", "2", "3", "4"),class = "factor"),
mang = c(100.346364791691, 61.6459563812475, -93.4372656495579, -150.308914571739),
mdisp = c(22.1760257078993, 16.1971728831951, 13.7224045052927, 16.3229969619169),
sd = c(88.7601477929364, 115.305326107927, 89.1303441207914, 75.4004747324955)),
row.names = c(NA, -4L),
class = c("tbl_df", "tbl", "data.frame"),
.Names = c("group", "mang", "mdisp", "sd"))
代码:
library(tidyverse)
ggplot(test)+
geom_rect(aes(xmin = mang - sd, xmax = mang + sd, ymin = 0,ymax = mdisp, fill = group))+
geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp))+
scale_x_continuous(breaks = c(-90, 0, 90, 180, 270, 360), limits = c(-180, 180))+
coord_polar(start = 2*pi, direction = -1)+
facet_grid(~group)+
ggtitle("polar plots with sd")
下面给出这张图:
如果我注释掉设置x比例#scale_x_continuous(breaks=c(-90,0,90, 180, 270, 360),limits=c(-180, 180))
的行,则这些矩形将出现在本图所示的位置,但是比例错误:
如何使比例尺和边界矩形都显示在同一图上?
答案 0 :(得分:1)
一种方法是自己计算回绕量并定义单独的矩形。例如:
test2 <- test %>%
mutate(xmin = mang - sd,
xmax = mang + sd) %>%
mutate(xmin1 = pmax(xmin, -180),
xmax1 = pmin(xmax, 180),
xmin2 = ifelse(xmin < -180, 2 * 180 + xmin, -180),
xmax2 = ifelse(xmax > 180, 2 * -180 + xmax, 180))
> test2
# A tibble: 4 x 10
group mang mdisp sd xmin xmax xmin1 xmax1 xmin2 xmax2
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 100. 22.2 88.8 11.6 189. 11.6 180 -180 -171.
2 2 61.6 16.2 115. -53.7 177. -53.7 177. -180 180
3 3 -93.4 13.7 89.1 -183. -4.31 -180 -4.31 177. 180
4 4 -150. 16.3 75.4 -226. -74.9 -180 -74.9 134. 180
图:
ggplot(test2) +
geom_rect(aes(xmin = xmin1, xmax = xmax1, ymin = 0, ymax = mdisp, fill = group)) +
geom_rect(aes(xmin = xmin2, xmax = xmax2, ymin = 0, ymax = mdisp, fill = group)) +
geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp)) +
scale_x_continuous(breaks = seq(-90, 180, 90), limits = c(-180, 180)) +
coord_polar(start = 2 * pi, direction = -1) +
facet_grid(~ group)
答案 1 :(得分:0)
通过结合之前的答案和Z.lin提供的解决方案,我最终获得了这些图的非优雅但准确的版本。也许有更好的方法,但是我的实际数据中没有那么多类别,因此像这样手动进行是合理的。
test3<-filter(test2, group!="2") # filter out the one that doesn't work
ggplot(test)+
geom_rect(aes(xmin = mang - sd, xmax = mang + sd, ymin = 0,ymax = mdisp))+
geom_rect(data=test3, aes(xmin = xmin1, xmax = xmax1, ymin = 0, ymax = mdisp)) +
geom_rect(data=test3, aes(xmin = xmin2, xmax = xmax2, ymin = 0, ymax = mdisp)) +
geom_segment(aes(x = mang, y = 0, xend = mang, yend = mdisp), color=group)+
scale_x_continuous(breaks = c(-90, 0, 90, 180, 270, 360), limits = c(-180, 180))+
coord_polar(start = 2*pi, direction = -1)+
facet_grid(~group)+
ggtitle("polar plots with sd")
所要寻找的
谢谢。
答案 2 :(得分:0)
一种更通用的解决方案,不排除第2组。它是答案1的更正版本。可以使用以下功能进行正确的包装。
...
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.listen([backlog])
sock.bind((host, client_port))
...
将此代码应用于当前问题
wrap_polar_seg <- function(x, w) {
a1 = x-w/2
a2 = x+w/2
u = matrix(nrow=length(x),ncol=5)
u[,5] = ifelse(a1 < 0, ifelse(a1 > -180 & a2 > -180, 0,1),
ifelse(a2 < 180 & a2 < 180,0,2))
u[,1] = ifelse(u[,5] == 2,a1, ifelse(u[,5]==1,360+a1,a1))
u[,2] = ifelse(u[,5] == 2,180, ifelse(u[,5]==1,180, a2))
u[,3] = ifelse(u[,5] == 2,a2-360, ifelse(u[,5]==1,a2, a1))
u[,4] = ifelse(u[,5] == 2,-180, ifelse(u[,5]==1,-180, a2))
u
}
结果是: