3

最近对 ggplot2 (2.2.0) 的更新破坏了我们的一些绘图,因为绘制点的顺序发生了变化。例如,下面的代码:

library(dplyr)
library(ggplot2)
library(tibble)


df <- tribble(~a, ~x, ~y,
              "I", "A",  2,
              "I", "B",  3,
              "II","A",  2,
              "II","B",  3)

ggplot(df, aes(x = x, y = y, color = a)) +
  geom_point(size = 5, position = position_dodge(width = 0.1))+
  coord_cartesian(ylim = c(0,15)) 

在 ggplot2 的两个最新版本之间产生不同的版本,

看这里

注意点重叠顺序的不同(即新版本与最左边的点重叠)。我可以通过反转因子顺序来反转类别重叠的顺序:

library(dplyr)
library(ggplot2)
library(tibble)
library(forcats)


df <- tribble(~a, ~x, ~y,
              "I", "A",  2,
              "I", "B",  3,
              "II","A",  2,
              "II","B",  3)

ggplot(df, aes(x = x, y = y, color = fct_rev(a))) +
  geom_point(size = 5, position = position_dodge(width = 0.1))+
  coord_cartesian(ylim = c(0,15)) 

但这无济于事,因为它现在也颠倒了躲避顺序。

这个情节

有谁知道重现以前行为的任何方法?是否可以在不更改闪避顺序的情况下手动反转绘制点的顺序?

4

1 回答 1

5

建立自己的位置闪避也不是太难:

library(ggplot2)

# My private Idaho^H^H^H^H^Hdodge ---------------------------------------------------

collide2 <- function(data, width = NULL, name, strategy, check.width = TRUE) {
  if (!is.null(width)) {
    if (!(all(c("xmin", "xmax") %in% names(data)))) {
      data$xmin <- data$x - width / 2
      data$xmax <- data$x + width / 2
    }
  } else {
    if (!(all(c("xmin", "xmax") %in% names(data)))) {
      data$xmin <- data$x
      data$xmax <- data$x
    }
    widths <- unique(data$xmax - data$xmin)
    widths <- widths[!is.na(widths)]
    width <- widths[1]
  }

  ####### THIS is the line that was added that is causing you angst
  # data <- data[order(data$xmin, -data$group), ]

  intervals <- as.numeric(t(unique(data[c("xmin", "xmax")])))
  intervals <- intervals[!is.na(intervals)]

  if (length(unique(intervals)) > 1 & any(diff(scale(intervals)) < -1e-6)) {
    warning(name, " requires non-overlapping x intervals", call. = FALSE)
  }

  if (!is.null(data$ymax)) {
    plyr::ddply(data, "xmin", strategy, width = width)
  } else if (!is.null(data$y)) {
    data$ymax <- data$y
    data <- plyr::ddply(data, "xmin", strategy, width = width)
    data$y <- data$ymax
    data
  } else {
    stop("Neither y nor ymax defined")
  }
}

position_dodge2 <- function(width = NULL) {
  ggproto(NULL, PositionDodge2, width = width)
}

PositionDodge2 <- ggproto(
  "PositionDodge", 
  Position,
  required_aes = "x",
  width = NULL,
  setup_params = function(self, data) {
    if (is.null(data$xmin) && is.null(data$xmax) && is.null(self$width)) {
      warning("Width not defined. Set with `position_dodge(width = ?)`",
              call. = FALSE)
    }
    list(width = self$width)
  },

  compute_panel = function(data, params, scales) {
    collide2(data, params$width, "position_dodge2", ggplot2:::pos_dodge, check.width = FALSE)
  }
)

# End new Dodge ---------------------------------------------------------------------

测试…</p>

library(dplyr)
library(tibble)
library(gridExtra)

df <- tribble(~a, ~x, ~y,
              "I", "A",  2,
              "I", "B",  3,
              "II","A",  2,
              "II","B",  3)

grid.arrange(
  ggplot(df, aes(x = x, y = y, color = a)) +
    geom_point(size = 5, position = position_dodge2(width = 0.1)) +
    coord_cartesian(ylim = c(0,15)) +
    labs(title="Old behaviour")
  ,
  ggplot(df, aes(x = x, y = y, color = a)) +
    geom_point(size = 5, position = position_dodge(width = 0.1)) +
    coord_cartesian(ylim = c(0,15)) +
    labs(title="New behaviour")
  ,
  ncol=2
)

在此处输入图像描述

于 2017-01-03T14:27:46.403 回答