[英]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.