【问题标题】:how to get ggplot2 axis to break at variable values?如何让 ggplot2 轴在变量值处中断?
【发布时间】:2018-05-25 16:15:36
【问题描述】:

这个@camille 代码使用 ggplot 生成了一个漂亮的帕累托图。

library(tidyverse)

d <- tribble(
    ~ category, ~defect,
    "price", 80,
    "schedule", 27,
    "supplier", 66,
    "contact", 94,
    "item", 33
) %>% arrange(desc(defect)) %>%
    mutate(
        cumsum = cumsum(defect),
        freq = round(defect / sum(defect), 3),
        cum_freq = cumsum(freq)
    ) %>%
    mutate(category = as.factor(category) %>% fct_reorder(defect))

brks <- unique(d$cumsum)

ggplot(d, aes(x = fct_rev(category))) +
    geom_col(aes(y = defect)) +
    geom_point(aes(y = cumsum)) +
    geom_line(aes(y = cumsum, group = 1)) +
    scale_y_continuous(sec.axis = sec_axis(~. / max(d$cumsum), labels = scales::percent), breaks = brks)

这几乎是完美的,只是我希望看到第二个 y 轴在累积 y 值处中断。这可以通过以下代码在 base-R 中实现。但是在ggplot中我该怎么做呢?

## Creating the d tribble
library(tidyverse)
d <- tribble(
  ~ category, ~defect,
  "price", 80,
  "schedule", 27,
  "supplier", 66,
  "contact", 94,
  "item", 33
)

## Creating new columns
d <- arrange(d, desc(defect)) %>%
  mutate(
    cumsum = cumsum(defect),
    freq = round(defect / sum(defect), 3),
    cum_freq = cumsum(freq)
  )

## Saving Parameters 
def_par <- par() 

## New margins
par(mar=c(5,5,4,5)) 

## bar plot, pc will hold x values for bars
pc = barplot(d$defect,  
             width = 1, space = 0.2, border = NA, axes = F,
             ylim = c(0, 1.05 * max(d$cumsum, na.rm = T)), 
             ylab = "Cummulative Counts" , cex.names = 0.7, 
             names.arg = d$category,
             main = "Pareto Chart (version 1)")

## Cumulative counts line 
lines(pc, d$cumsum, type = "b", cex = 0.7, pch = 19, col="cyan4")

## Framing plot
box(col = "grey62")

## adding axes
axis(side = 2, at = c(0, d$cumsum), las = 1, col.axis = "grey62", col = "grey62", cex.axis = 0.8)
axis(side = 4, at = c(0, d$cumsum), labels = paste(c(0, round(d$cum_freq * 100)) ,"%",sep=""), 
     las = 1, col.axis = "cyan4", col = "cyan4", cex.axis = 0.8)

## restoring default paramenter
par(def_par) 

Camille 有一些想法,但他们仍然徘徊,“最新版本的 ggplot2 允许辅助轴,但它需要基于主轴的转换。在这种情况下,这意味着它应该采用主轴轴的值并除以最大值得到百分比。”。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:
    brks <- unique(d$cumsum)
    brks2 <- unique(d$cumsum / max(d$cumsum))
    
    ggplot(d, aes(x = fct_rev(category))) +
      geom_col(aes(y = defect)) +
      geom_point(aes(y = cumsum)) +
      geom_line(aes(y = cumsum, group = 1)) +
      scale_y_continuous(sec.axis = sec_axis(~. / max(d$cumsum), labels = scales::percent, breaks = brks2), breaks = brks)
    

    【讨论】:

    • +1 对我的旧代码进行了出色、简单(并且第一次应该很明显!)的改进。昨晚我提出了一个问题,想知道如何在这些自定义轴中使用ggplot 的内部中断计算,这让我对此更加好奇
    【解决方案2】:

    这对上一个问题中我之前的代码的唯一改进,@Jack Brookes 的回答是我消除了在 ggplot 调用之外计算两组中断的需要。相反,我只是将累积原始数字的中断设为unique(d$cumsum),将累积频率的中断设为unique(d$cumfreq)。在这两个方面,我都在开头添加了 0,因为否则不会在 0 处放置中断。


    library(tidyverse)
    library(scales)
    
    d <- tribble(
      ~ category, ~defect,
      "price", 80,
      "schedule", 27,
      "supplier", 66,
      "contact", 94,
      "item", 33
    ) %>% arrange(desc(defect)) %>%
      mutate(
        cumsum = cumsum(defect),
        freq = round(defect / sum(defect), 3),
        cum_freq = cumsum(freq)
      ) %>%
      mutate(category = as.factor(category) %>% fct_reorder(defect))
    
    ggplot(d, aes(x = fct_rev(category))) +
      geom_col(aes(y = defect)) +
      geom_point(aes(y = cumsum)) +
      geom_line(aes(y = cumsum, group = 1)) +
      scale_y_continuous(breaks = c(0, unique(d$cumsum)),
        sec.axis = sec_axis(~. / max(d$cumsum), labels = scales::percent,
           breaks = c(0, unique(d$cum_freq))) 
      ) +
      theme(panel.grid.minor = element_blank())
    

    【讨论】:

    • 双 y 轴已被证明难以阅读。也许这里更好的解决方案是将百分比作为geom_text ?
    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    相关资源
    最近更新 更多