我有一个与此类似的数据集:
x <- 100 - abs(rnorm(1e6, 0, 5))
y <- 50 + rnorm(1e6, 0, 3)
dist <- sqrt((x - 100)^2 + (y - 50)^2)
z <- exp(-(dist / 8)^2)
可以如下显示:
data.frame(x, y, z) %>%
ggplot() + geom_point(aes(x, y, color = z))
我想做的是一个堆叠的半圆图,在后续层中具有z的平均值。我认为可以将geom_col
和coord_polar()
组合使用,尽管我能得到的最远距离是
data.frame(x, y, z, dist) %>%
mutate(dist_fct = cut(dist, seq(0, max(dist), by = 5))) %>%
ggplot() + geom_bar(aes(x = 1, y = 1, fill = dist_fct), stat = 'identity', position = 'fill') +
coord_polar()
这显然与预期相差甚远(各层的大小应相等,图的右半部分应剪裁)。
问题是由于进一步使用coord_polar()
,我不能真正使用annotate_custom()
。所以我的问题是:
coord_polar()
吗? coord_polar()
完成?答案 0 :(得分:3)
如果您想要简单的半径带,也许像您在问题中所描绘的那样,可以进行如下操作:
# your original sample data
x <- 100 - abs(rnorm(1e6, 0, 5))
y <- 50 + rnorm(1e6, 0, 3)
dist <- sqrt((x - 100)^2 + (y - 50)^2)
nbr_bands <- 6 # set nbr of bands to plot
# calculate width of bands
band_width <- max(dist)/(nbr_bands-1)
# dist div band_width yields an integer 0 to nbr bands
# as.factor makes it categorical, which is what you want for the plot
band = as.factor(dist %/% (band_width))
library(dplyr)
library(ggplot2)
data.frame(x, y, band) %>%
ggplot() + geom_point(aes(x, y, color = band)) + coord_fixed() +
theme_dark() # dark theme
第一次尝试时,最好使用方便的cut()
函数来计算半径颜色类别。
一种获得分类(离散)颜色(而不是连续着色)的方法是对绘图颜色组进行设置,将aes color=
设置为一个因子列。
要直接从cut()
获取因子,可以使用选项ordered_result=TRUE
:
band <- cut(dist, nbr_bands, ordered_result=TRUE, labels=1:nbr_bands) # also use `labels=` to specify your own labels
data.frame(x, y, band) %>%
ggplot() + geom_point(aes(x, y, color = band)) + coord_fixed()
或更简单地说,您可以使用不带选项的cut()
并使用as.factor()
转换为因数:
band <- as.factor( cut(dist, nbr_bands, labels=FALSE) )
data.frame(x, y, band) %>%
ggplot() + geom_point(aes(x, y, color = band)) + coord_fixed()
答案 1 :(得分:3)
ggforce
包中的圆形和圆弧绘图功能很有用:
# data
set.seed(1234)
df <- data.frame(x = 100 - abs(rnorm(1e6, 0, 5)),
y = 50 + rnorm(1e6, 0, 3)) %>%
mutate(dist = sqrt((x - 100)^2 + (y - 50)^2)) %>%
mutate(z = exp(-(dist / 8)^2))
# define cut-off values
cutoff.values <- seq(0, ceiling(max(df$dist)), by = 5)
df %>%
# calculate the mean z for each distance band
mutate(dist_fct = cut(dist, cutoff.values)) %>%
group_by(dist_fct) %>%
summarise(z = mean(z)) %>%
ungroup() %>%
# add the cutoff values to the dataframe for inner & outer radius
arrange(dist_fct) %>%
mutate(r0 = cutoff.values[-length(cutoff.values)],
r = cutoff.values[-1]) %>%
# add coordinates for circle centre
mutate(x = 100, y = 50) %>%
# plot
ggplot(aes(x0 = x, y0 = y,
r0 = r0, r = r,
fill = z)) +
geom_arc_bar(aes(start = 0, end = 2 * pi),
color = NA) + # hide outline
# force equal aspect ratio in order to get true circle
coord_equal(xlim = c(70, 100), expand = FALSE)
在我的计算机上,图生成花费了不到1秒的时间。您的可能会有所不同。
答案 2 :(得分:2)
我不确定这是否满足所有条件,但这应该是一个开始。为了减少打印时间,我将数据汇总到一个网格中,使您可以使用geom_raster
。我并不完全了解这些中断以及您正在使用的所有内容,因此您可能需要调整一些如何划分数据以形成不同频段的方法。我用cut_interval
和cut_width
尝试了几种方法,这是插入不同选项(例如乐队的数量或宽度)的好地方。
由于您提到要获得每个频段的平均z
,所以我将按照网格x
和y
以及切线dist
进行分组,然后使用{ {1}}用于设置频段。我迈出了一步,制作如示例中的标签-您可能想要反转它们或调整它们的位置-但这是通过获取每个波段的因子水平的数目来实现的。
z
要制作标签,请对数据进行汇总,使其每条带具有一行-我这样做是通过取网格library(tidyverse)
set.seed(555)
n <- 1e6
df <- data_frame(
x = 100 - abs(rnorm(n, 0, 5)),
y = 50 + rnorm(n, 0, 3),
dist = sqrt((x - 100)^2 + (y - 50)^2),
z = exp(-(dist / 8)^2)
) %>%
mutate(brk = cut(dist, seq(0, max(dist), by = 5), include.lowest = T))
summarized <- df %>%
filter(!is.na(brk)) %>%
mutate(x_grid = floor(x), y_grid = floor(y)) %>%
group_by(x_grid, y_grid, brk) %>%
summarise(avg_z = mean(z)) %>%
ungroup() %>%
# mutate(z_brk = cut_width(avg_z, width = 0.15)) %>%
mutate(z_brk = cut_interval(avg_z, n = 9)) %>%
mutate(brk_num = as.numeric(z_brk))
head(summarized)
#> # A tibble: 6 x 6
#> x_grid y_grid brk avg_z z_brk brk_num
#> <dbl> <dbl> <fct> <dbl> <fct> <dbl>
#> 1 75 46 (20,25] 0.0000697 [6.97e-05,0.11] 1
#> 2 75 47 (20,25] 0.000101 [6.97e-05,0.11] 1
#> 3 75 49 (20,25] 0.0000926 [6.97e-05,0.11] 1
#> 4 75 50 (20,25] 0.0000858 [6.97e-05,0.11] 1
#> 5 75 52 (20,25] 0.0000800 [6.97e-05,0.11] 1
#> 6 76 51 (20,25] 0.000209 [6.97e-05,0.11] 1
的最小值,然后使用x
的平均值,以便出现在情节的中间。
y
labels <- summarized %>%
group_by(brk_num) %>%
summarise(min_x = min(x_grid)) %>%
ungroup() %>%
mutate(y_grid = mean(summarized$y_grid))
head(labels)
#> # A tibble: 6 x 3
#> brk_num min_x y_grid
#> <dbl> <dbl> <dbl>
#> 1 1 75 49.7
#> 2 2 88 49.7
#> 3 3 90 49.7
#> 4 4 92 49.7
#> 5 5 93 49.7
#> 6 6 94 49.7
非常适合这些情况,即您将数据存储在均匀间隔的网格中,每个位置只需要均匀的图块。此时,汇总数据有595行,而不是原始的100万行,因此绘制时间不应该成为问题。
geom_raster
由reprex package(v0.2.1)于2018-11-04创建