R语言 Alpha渐变与geom_smooth

ryhaxcpt  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(93)

我有下面的网格散点图。对于每个面板中的每个物种,我希望平滑线反映数据的密度。
我的想法是先将x轴的值切到bin中,然后计算每种物种每种性别每年的观察次数,并将该计数变量用于alpha。但它似乎不起作用(即使使用stat_smooth(geom= 'line'...))。
例如,在左下角的面板(女性,2009年)中,我希望线条在x值15 - 16之间相对更透明,然后在16-18之间更暗,并且在18以上非常透明。
谢谢

library(tidyverse)
library(palmerpenguins)
# Create a new variable for 
# binned values of bill_depth_mm
# for each species in each grid panel
penguins_cut <- penguins %>% 
  group_by(species, sex, year) %>% 
  mutate(xbin = cut(
    bill_depth_mm,
    breaks = 4 )) %>% 
  ungroup()

# Count the number of observations
count_data <- penguins_cut %>% 
  group_by(species, sex, year, xbin) %>% 
  summarise(count = n()) %>% 
  ungroup()
#> `summarise()` has grouped output by 'species', 'sex', 'year'. You can override
#> using the `.groups` argument.

df <- left_join(penguins_cut,
                count_data,
                by = c("species", "sex", "year", "xbin"))

ggplot(df, 
       aes(x = bill_depth_mm, 
           y = bill_length_mm,
           colour = species)) +
  geom_point(alpha = 0.5) +
  geom_smooth(aes(alpha = count),
              geom='line', se=FALSE)+  
  facet_grid(year ~ sex)

字符串
x1c 0d1x的数据
创建于2023-11-09带有reprex v2.0.2

kb5ga3dv

kb5ga3dv1#

这很棘手,但并非不可能。您需要预先计算密度和平滑度,然后使用geom_segment绘图
数据争论就像是

df <- left_join(penguins_cut,
                count_data,
                by = c("species", "sex", "year", "xbin")) %>%
  filter(complete.cases(.))

smooth_df <- df %>%
  group_by(sex, species, year) %>%
  reframe(bill = density(bill_depth_mm, from = 13, to = 22)$x,
          density = density(bill_depth_mm, from = 13, to = 22)$y,
          bill_length_mm = predict(loess(bill_length_mm ~ bill_depth_mm,
                              control = loess.control(surface = "direct"),
                              span = 1),
                              newdata = bill)) %>%
  rename(bill_depth_mm = bill) %>%
  group_by(sex, species, year) %>%
  mutate(xend = lag(bill_depth_mm), 
         yend = lag(bill_length_mm),
         density = density / max(density))

字符串
绘图代码为:

ggplot(df, aes(x = bill_depth_mm, 
           y = bill_length_mm,
           colour = species)) +
  geom_point(size = 1) +
  geom_segment(aes(alpha = density, xend = xend, yend = yend), 
               data = smooth_df, linewidth = 1.5) +
  facet_grid(year ~ sex) +
  scale_alpha(range = c(0, 1)) +
  theme_minimal() +
  theme(panel.border = element_rect(fill = NA)) +
  ylim(30, 60)


的数据
我不确定这是否会给情节增加什么,但我想这有点酷。

编辑

如果loess不适合您的数据,您可以将gam与平滑器一起使用。例如,下面是如何使用gam创建smooth_df对象:

smooth_df <- df %>%
  group_by(sex, species, year) %>%
  reframe(bill = density(bill_depth_mm, from = 13, to = 22)$x,
          density = density(bill_depth_mm, from = 13, to = 22)$y,
          bill_length_mm = predict(
            mgcv::gam(bill_length_mm ~ s(bill_depth_mm, k = 8, bs = "cs")),
                      newdata = data.frame(bill_depth_mm = bill))) %>%
  rename(bill_depth_mm = bill) %>%
  group_by(sex, species, year) %>%
  mutate(xend = lag(bill_depth_mm), 
         yend = lag(bill_length_mm),
         density = density / max(density))


使用相同的绘图代码,这将产生:

相关问题