使用 y 轴值在 ggplot2 中创建辅助 x 轴

using y-axis values to create secondary x-axis in ggplot2

我想创建一个带有百分位数的点图,看起来像这样-

这是我用来创建点图的 ggplot2 代码。我想更改两件事:

  1. 我可以在 y 轴上绘制百分位数,但我想要这些 x 轴上的值(如上图所示)。 注意 坐标翻转了。
  2. 轴不显示标签 最小值(例如百分位轴标签从 25 开始 当他们应该从 0 开始时。)
# loading needed libraries
library(tidyverse)
library(ggstatsplot)

# creating dataframe with mean mileage per manufacturer
cty_mpg <- ggplot2::mpg %>%
  dplyr::group_by(.data = ., manufacturer) %>%
  dplyr::summarise(.data = ., mileage = mean(cty, na.rm = TRUE)) %>%
  dplyr::rename(.data = ., make = manufacturer) %>%
  dplyr::arrange(.data = ., mileage) %>%
  dplyr::mutate(.data = ., make = factor(x = make, levels = .$make)) %>%
  dplyr::mutate(
    .data = .,
    percent_rank = (trunc(rank(mileage)) / length(mileage)) * 100
  ) %>%
  tibble::as_data_frame(x = .)

# plot
ggplot2::ggplot(data = cty_mpg, mapping = ggplot2::aes(x = make, y = mileage)) +
  ggplot2::geom_point(col = "tomato2", size = 3) + # Draw points
  ggplot2::geom_segment(
    mapping = ggplot2::aes(
      x = make,
      xend = make,
      y = min(mileage),
      yend = max(mileage)
    ),
    linetype = "dashed",
    size = 0.1
  ) + # Draw dashed lines
  ggplot2::scale_y_continuous(sec.axis = ggplot2::sec_axis(trans = ~(trunc(rank(.)) / length(.)) * 100, name = "percentile")) +
  ggplot2::coord_flip() +
  ggplot2::labs(
    title = "City mileage by car manufacturer",
    subtitle = "Dot plot",
    caption = "source: mpg dataset in ggplot2"
  ) +
  ggstatsplot::theme_ggstatsplot()

reprex package (v0.2.0.9000) 创建于 2018-08-17。

我不是 100% 肯定理解你真正想要的,但下面是我尝试用 mpg 数据重现第一张图片:

require(ggplot2)

data <- aggregate(cty~manufacturer, mpg, FUN = mean)
data <- data.frame(data[order(data$cty), ], rank=1:nrow(data))

g <- ggplot(data, aes(y = rank, x = cty))
g <- g + geom_point(size = 2)
g <- g + scale_y_continuous(name = "Manufacturer", labels = data$manufacturer, breaks = data$rank,
                            sec.axis = dup_axis(name = element_blank(),
                                                breaks = seq(1, nrow(data), (nrow(data)-1)/4),
                                                labels = 25 * 0:4))
g <- g + scale_x_continuous(name = "Mileage", limits = c(10, 25),
                            sec.axis = dup_axis(name = element_blank()))
g <- g + theme_classic()
g <- g + theme(panel.grid.major.y = element_line(color = "black", linetype = "dotted"))

print(g)

产生:

data <- aggregate(cty~manufacturer, mpg, FUN = mean)
data <- data.frame(data[order(data$cty), ], rank=1:nrow(data))

这两行生成图表的数据。基本上我们需要制造商、里程(ctymanufacturer的平均值)和排名。

g <- g + scale_y_continuous(name = "Manufacturer", labels = data$manufacturer, breaks = data$rank,
                            sec.axis = dup_axis(name = element_blank(),
                                                breaks = seq(1, nrow(data), (nrow(data)-1)/4),
                                                labels = 25 * 0:4))

请注意,此处的比例使用 rank 而不是 manufacturer。要显示制造商的名称,您必须使用 labels 属性 并且必须为每个值强制中断(请参阅 属性 breaks)。

第二个y-axis是使用sec.axis属性生成的。使用 dup_axis 非常简单,可以轻松复制轴。通过替换 labelsbreaks,您可以显示百分比值。

g <- g + theme(panel.grid.major.y = element_line(color = "black", linetype = "dotted"))

水平线只是主网格。在我看来,这比 geom_segments 更容易操作。

关于您的问题 1,您可以使用 coord_flip 轻松翻转坐标,稍作调整。替换以下行:

g <- g + theme(panel.grid.major.y = element_line(color = "black", linetype = "dotted")

通过以下两行:

g <- g + coord_flip()
g <- g + theme(panel.grid.major.x = element_line(color = "black", linetype = "dotted"),
               axis.text.x = element_text(angle = 90, hjust = 1))

产生:

关于您的问题 2,问题是值 0% 超出了限制。您可以通过更改计算百分比的方式(从零开始而不是从一开始)来解决此问题,或者您可以扩展绘图的限制以包含值零,但是没有任何点与 0% 关联。