【问题标题】:ggplot custom endpoints of lollipop chartsggplot 棒棒糖图表的自定义端点
【发布时间】:2018-11-14 10:02:42
【问题描述】:

我有以下从the rgraph gallery 获取的棒棒糖/哑铃 ggplot 的最小可重复示例。

如何使项目符号端点因查找表而异?行数将是动态的,因此不应对其进行硬编码。因此,例如,如果下端为负,则显示左箭头,如果为零,则应显示子弹,如果为正,则应显示右箭头。

我还想根据这些改变每条线/哑铃的颜色。因此,例如,如果下端为负,则整条线为红色,如果它触及零,则整条线为蓝色,严格为正,则应显示为绿色。

library(tidyverse)

# Create data
value1=abs(rnorm(26))*2
data=data.frame(x=LETTERS[1:26], value1=value1, value2=value1+1+rnorm(26, sd=1) )

# Reorder data using average?
data = data %>% rowwise() %>% mutate( mymean = mean(c(value1,value2) )) %>% arrange(mymean) %>% mutate(x=factor(x, x))

# plot
ggplot(data) +
  geom_segment( aes(x=x, xend=x, y=value1, yend=value2), color="grey") +
  geom_point( aes(x=x, y=value1), color=rgb(0.2,0.7,0.1,0.5), size=3 ) +
  geom_point( aes(x=x, y=value2), color=rgb(0.7,0.2,0.1,0.5), size=3 ) +
  coord_flip() 

# With a bit more style
ggplot(data) +
  geom_segment( aes(x=x, xend=x, y=value1, yend=value2), color="grey") +
  geom_point( aes(x=x, y=value1), color=rgb(0.2,0.7,0.1,0.5), size=3 ) +
  geom_point( aes(x=x, y=value2), color=rgb(0.7,0.2,0.1,0.5), size=3 ) +
  coord_flip()+
  theme_light() +
  theme(
    legend.position = "none",
    panel.border = element_blank()
  ) +
  xlab("") +
  ylab("Value of Y")

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    这是一种方法,但您必须手动构建图例(如果有)。我担心您会以您想要设置颜色的方式掩盖value1value2 中的哪一个在左侧(IMO 颜色应始终与度量名称相关联,但您是想要做的人这样)。它使用纯文本形状作为左侧项目符号,因为您必须做一些有趣的“arrow()”-ing 或使用使用表情符号或图像的自定义几何图形,否则 (其他也知道如何做到这一点的人并且实际上有空闲时间肯定应该回答这些问题,因为考虑到那些geoms 的脆弱性,OP 可能会有很多来回的回答,而我只是没有那个周期它可能会采取不断调整答案,直到所有这些都在 OP 的系统上工作)

    library(hrbrthemes)
    library(tidyverse)
    # Create data
    set.seed(2018-11-14)
    
    data_frame(
      cond = LETTERS[1:26], 
      value1 = abs(rnorm(26)) * 2,
      value2 = value1 + 1 + rnorm(26, sd = 1)
    ) -> xdf
    
    # ensure there are representative conditions to test logic
    xdf[9, "value1"] <- 0
    xdf[10, "value1"] <- 1.1
    xdf[11, "value2"] <- 0
    xdf[21, "value2"] <- -xdf[21, "value2"]
    xdf[26, "value1"] <- -xdf[26, "value1"]
    xdf[26, "value2"] <- 0
    
    print(xdf, n=26)
    
    # Reorder data using average?
    rowwise(xdf) %>% 
      mutate(mymean = mean(c(value1, value2))) %>% 
      arrange(mymean) %>% 
      mutate(x = factor(cond, cond)) %>% 
      mutate(left_shp = case_when(
        (value1 < 0) | (value2 < 0) ~ "<",
        (value1 == 0) | (value2 == 0) ~ "•",
        (value1 > 0) & (value2 > 0) ~ ">"
      )) %>% 
      mutate(left_size = case_when(
        (value1 < 0) | (value2 < 0) ~ 6,
        (value1 == 0) | (value2 == 0) ~ 11,
        (value1 > 0) & (value2 > 0) ~ 6
      )) %>% 
      mutate(hjust = case_when(
        (value1 < 0) | (value2 < 0) ~ 0.2,
        (value1 == 0) | (value2 == 0) ~ 0.5,
        (value1 > 0) & (value2 > 0) ~ 0.5
      )) %>% 
      mutate(
        col = case_when(
          (value1 < 0) | (value2 < 0) ~ "#cb181d",
          (value1 == 0) | (value2 == 0) ~ "#2171b5",
          (value1 > 0) & (value2 > 0) ~ "#238b45"
        )
      ) %>% 
      mutate(left = ifelse(value1 < value2, value1, value2)) %>% 
      mutate(right = ifelse(value1 > value2, value1, value2)) -> xdf
    
    # plot
    ggplot(xdf) +
      geom_segment(
        aes(x = left, xend = right, y = cond, yend = cond, color = I(col)), size = 1
      ) +
      geom_text(
        aes(x = left, y = cond, color = col, label = left_shp, hjust = I(hjust), size = I(left_size))
      ) +
      geom_point(aes(x = right, y = cond, color = col), size = 3) +
      labs(x=NULL, y= NULL) +
      theme_ipsum_rc(grid="X")
    

    【讨论】: