[英]How to draw a radar plot in ggplot using polar coordinates?
我正在尝试使用ggplot按照图形语法的指导绘制雷达图。 我知道ggradar包,但基于语法,看起来coord_polar
应该足够了。 这是语法中的伪代码:
所以我觉得这样的东西可能会起作用,但是,区域图的轮廓是弯曲的,好像我使用了geom_line
:
library(tidyverse)
dd <- tibble(category = c('A', 'B', 'C'), value = c(2, 7, 4))
ggplot(dd, aes(x = category, y = value, group=1)) +
coord_polar(theta = 'x') +
geom_area(color = 'blue', alpha = .00001) +
geom_point()
虽然我明白为什么geom_line
在绘制弧形一次coord_polar
,我从图形的语法解释的理解是,有可能是一个元素/ GEOM area
,可以绘制直线:
这是关于图9.29形状的一个技术细节。 为什么该区域的外边缘图形是一组直线而不是弧线? 答案与被测量的内容有关。 由于区域是分类变量,因此链接区域的线段不在图表的度量区域中。 也就是说,区域之间的域的片段是不可测量的,因此连接它们的直线或边缘是任意的并且可能不经历几何变换。 该图的语法规范还有另一个问题。 你能发现它吗? 撤消极地变换并思考情节的领域。 我们骗了。
为了完整起见,这个问题来源于我在极地系统中绘制的另一个问题。
tl; dr我们可以编写一个函数来解决这个问题。
实际上,ggplot使用一种称为数据咀嚼的过程来为非线性坐标系绘制线条。 它基本上分解了许多部分的直线,并在各个部分上应用坐标变换,而不仅仅是线的起点和终点。
如果我们查看GeomArea$draw_group
的面板绘图代码:
function (data, panel_params, coord, na.rm = FALSE)
{
...other_code...
positions <- new_data_frame(list(x = c(data$x, rev(data$x)),
y = c(data$ymax, rev(data$ymin)), id = c(ids, rev(ids))))
munched <- coord_munch(coord, positions, panel_params)
ggname("geom_ribbon", polygonGrob(munched$x, munched$y, id = munched$id,
default.units = "native", gp = gpar(fill = alpha(aes$fill,
aes$alpha), col = aes$colour, lwd = aes$size * .pt,
lty = aes$linetype)))
}
我们可以看到coord_munch
在传递给polygonGrob
之前应用于数据, polygonGrob
是绘制数据的网格包函数。 这种情况发生在我检查过的几乎任何基于行的geom中。
随后,我们想知道coord_munch
发生了coord_munch
:
function (coord, data, range, segment_length = 0.01)
{
if (coord$is_linear())
return(coord$transform(data, range))
...other_code...
munched <- munch_data(data, dist, segment_length)
coord$transform(munched, range)
}
我们发现前面提到的逻辑非线性坐标系在许多部分中分解线,由ggplot2:::munch_data
处理。
在我看来,我们可以通过某种方式将coord$is_linear()
的输出设置为true来欺骗ggplot转换为直线。
幸运的是,如果我们只是覆盖is_linear()
函数返回TRUE
,我们就不必通过做一些基于ggproto的深层东西来弄脏手:
# Almost identical to coord_polar()
coord_straightpolar <- function(theta = 'x', start = 0, direction = 1, clip = "on") {
theta <- match.arg(theta, c("x", "y"))
r <- if (theta == "x")
"y"
else "x"
ggproto(NULL, CoordPolar, theta = theta, r = r, start = start,
direction = sign(direction), clip = clip,
# This is the different bit
is_linear = function(){TRUE})
}
所以现在我们可以用极坐标中的直线绘制:
ggplot(dd, aes(x = category, y = value, group=1)) +
coord_straightpolar(theta = 'x') +
geom_area(color = 'blue', alpha = .00001) +
geom_point()
现在公平地说,我不知道这种变化会产生什么样的意外后果。 至少现在我们知道为什么ggplot会这样做,以及我们可以做些什么来避免它。
编辑:不幸的是,我不知道一个简单/优雅的方式来连接轴限制点,但你可以尝试这样的代码:
# Refactoring the data
dd <- data.frame(category = c(1,2,3,4), value = c(2, 7, 4, 2))
ggplot(dd, aes(x = category, y = value, group=1)) +
coord_straightpolar(theta = 'x') +
geom_path(color = 'blue') +
scale_x_continuous(limits = c(1,4), breaks = 1:3, labels = LETTERS[1:3]) +
scale_y_continuous(limits = c(0, NA)) +
geom_point()
关于极坐标和跨越边界的一些讨论,包括我自己尝试解决这个问题,可以在这里看到geom_path()拒绝在coord_polar()中越过0/360行
EDIT2:
我错了,无论如何它似乎相当微不足道。 假设dd
是你原来的tibble:
ggplot(dd, aes(x = category, y = value, group=1)) +
coord_straightpolar(theta = 'x') +
geom_polygon(color = 'blue', alpha = 0.0001) +
scale_y_continuous(limits = c(0, NA)) +
geom_point()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.