如何使用极坐标在ggplot中绘制雷达图? [英] How to draw a radar plot in ggplot using polar coordinates?

查看:326
本文介绍了如何使用极坐标在ggplot中绘制雷达图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ggplot遵循图形语法的指导方针绘制雷达图.我知道 ggradar 包,但是根据语法,它看起来像coord_polar应该是在这里足够了.这是语法中的伪代码:

I am trying to use ggplot to draw a radar-chart following the guidelines from the Grammar of Graphics. I am aware of the ggradar package but based on the grammar it looks like coord_polar should be enough here. This is the pseudo-code from the grammar:

所以我认为类似的方法可能有用,但是,面积图的轮廓是弯曲的,就像使用geom_line一样:

So I thought something like this may work, however, the contour of the area chart is curved as if I used 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_linecoord_polar中绘制一次弧,但是我对图形语法的理解是,可能有一个元素/几何图形area可以绘制直线:

While I understand why geom_line draws arcs once in coord_polar, my understanding of the explanation from the Grammar of Graphics is that there may be an element/geom area that could plot straight lines:

这是一个有关图9.29形状的技术细节.为什么 是区域图形的外边缘而是一组直线 弧线?答案与被测物有关.自从 region是一个分类变量,线段链接区域 不在图表的指标区域中.也就是说, 区域之间的区域无法测量,因此直线 或链接它们的边是任意的,也许不受限制 几何变换.还有另一个问题 该图的语法规范.你能发现吗?撤消 极性变换,并考虑图的范围.我们 被骗了.

here is one technical detail concerning the shape of Figure 9.29. Why is the outer edge of the area graphic a set of straight lines instead of arcs? The answer has to do with what is being measured. Since region is a categorical variable, the line segments linking regions are not in a metric region of the graph. That is, the segments of the domain between regions are not measurable and thus the straight lines or edges linking them are arbitrary and perhaps not subject to geometric transformation. There is one other problem with the grammatical specification of this figure. Can you spot it? Undo the polar trans- formation and think about the domain of the plot. We cheated.

出于完整性考虑,此问题源自

For completeness, this question derives from this other question I asked about plotting in polar system.

推荐答案

tl; dr;我们可以编写函数来解决此问题.

tl;dr we can write a function to solve this problem.

实际上,ggplot对非线性坐标系使用称为数据处理的过程来画线.它基本上是将多条直线分解成一条直线,并将坐标变换应用于单个零件,而不仅仅是行的起点和终点.

Indeed, ggplot uses a process called data munching for non-linear coordinate systems to draw lines. It basically breaks up a straight line in many pieces, and applies the coordinate transformation on the individual pieces instead of merely the start- and endpoints of lines.

如果我们查看例如GeomArea$draw_group的面板绘图代码:

If we look at the panel drawing code of for example 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)))
}

我们可以看到,在将数据传递给polygonGrob之前,已将coord_munch应用于数据,这是绘制数据所必需的网格包函数.在我检查过的几乎所有基于行的几何图形中都会发生这种情况.

We can see that a coord_munch is applied to the data before it is passed to polygonGrob, which is the grid package function that matters for drawing the data. This happens in almost any line-based geom for which I've checked this.

随后,我们想知道coord_munch中发生的事情:

Subsequently, we would like to know what is going on in 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处理.

We find the logic I mentioned earlier that non-linear coordinate systems break up lines in many pieces, which is handled by ggplot2:::munch_data.

在我看来,通过某种方式将coord$is_linear()的输出设置为始终为真,我们可以欺骗ggplot来转换直线.

It would seem to me that we can trick ggplot into transforming straight lines, by somehow setting the output of coord$is_linear() to always be true.

对我们来说幸运的是,如果我们只是重写is_linear()函数以返回TRUE:

Lucky for us, we wouldn't have to get our hands dirty by doing some deep ggproto based stuff if we just override the is_linear() function to return TRUE:

# 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})
}

现在我们可以在极坐标中用直线画出

So now we can plot away with straight lines in polar coordinates:

ggplot(dd, aes(x = category, y = value, group=1)) +
  coord_straightpolar(theta = 'x') +
  geom_area(color = 'blue', alpha = .00001) +
  geom_point()

坦白地说,我不知道此更改会带来哪些意想不到的后果.至少现在我们知道了为什么ggplot会表现出这种方式,以及如何避免这种情况.

Now to be fair, I don't know what the unintended consequences are for this change. At least now we know why ggplot behaves this way, and what we can do to avoid it.

不幸的是,我不知道一种简单/优雅的方法来跨轴限制连接点,但是您可以尝试这样的代码:

Unfortunately, I don't know of an easy/elegant way to connect the points across the axis limits but you could try code like this:

# 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()

有关极坐标和越过边界的一些讨论,包括我自己解决该问题的尝试,请参见此处

Some discussion about polar coordinates and crossing the boundary, including my own attempt at solving that problem, can be seen here geom_path() refuses to cross over the 0/360 line in coord_polar()

我弄错了,无论如何看起来都很琐碎.假设dd是您的原始文字:

I'm mistaken, it seems quite trivial anyway. Assume dd is your original 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()

这篇关于如何使用极坐标在ggplot中绘制雷达图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆