在ggplot2中使用coord_flip()和facet_wrap(scales =“free_y”)似乎给出了意想不到的facet轴刻度标记和刻度标签

时间:2012-09-24 07:48:50

标签: r ggplot2

我正在尝试使用翻转坐标创建一个多面图,其中每个方面允许一个且只有一个轴变化:

require(ggplot2)
p <- qplot(displ, hwy, data = mpg)
p + facet_wrap(~ cyl, scales = "free_y") + coord_flip()

enter image description here

这个图对我来说并不令人满意,因为每个图都会重复出现错误的刻度线和刻度标签。我希望每个水平轴上都有刻度线,而不是每个垂直轴。

这是出乎意料的行为,因为该图表示顶部面板的水平轴刻度标记与底部面板相同,但它们不是。要看到这个运行:

p <- qplot(displ, hwy, data = mpg)
p + facet_wrap(~ cyl, scales = "fixed") + coord_flip()

所以我的问题是:有没有办法去除右刻面的垂直轴刻度线,并在顶面添加水平轴刻度线和标签?

正如保罗在下面深刻地指出的那样,我给出的例子可以通过在qplot()中交换x和y并避免使用coord_flip()来解决,但是这并不适用于所有的geoms,例如,如果我想要一个水平刻面条我可以运行自由水平轴的情节:

c <- ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar()
c + facet_wrap(~cut, scales = "free_y") + coord_flip()

image

这些面具有可变的水平轴,但重复的垂直轴刻度线而不是重复的水平轴刻度线。我不认为保罗的伎俩会在这里起作用,因为与散点图不同,条形图不是旋转对称的。

我很想听到任何部分或完整的解决方案。

3 个答案:

答案 0 :(得分:8)

coord_flipfacet_wrap结合使用是个问题所在。首先,您将某个轴定义为自由(x轴),然后交换轴,使y轴自由。现在这在ggplot2中没有很好地再现。

在您的第一个示例中,我建议您不要使用coord_flip,而只是在调用qplot并使用free_x时交换变量:

p <- qplot(hwy, displ, data = mpg)
p + facet_wrap(~ cyl, scales = "free_x")

enter image description here

答案 1 :(得分:6)

这是我第二次或第三次遇到这个问题。我发现我可以通过定义自定义geom来破解我自己的解决方案。

geom_bar_horz <- function (mapping = NULL, data = NULL, stat = "bin", position = "stack", ...) {
  GeomBar_horz$new(mapping = mapping, data = data, stat = stat, position = position, ...)
}

GeomBar_horz <- proto(ggplot2:::Geom, {
  objname <- "bar_horz"

  default_stat <- function(.) StatBin
  default_pos <- function(.) PositionStack
  default_aes <- function(.) aes(colour=NA, fill="grey20", size=0.5, linetype=1, weight = 1, alpha = NA)

  required_aes <- c("y")

  reparameterise <- function(., df, params) {
    df$width <- df$width %||%
      params$width %||% (resolution(df$x, FALSE) * 0.9)
    OUT <- transform(df,
              xmin = pmin(x, 0), xmax = pmax(x, 0),
              ymin = y - .45, ymax = y + .45, width = NULL
    )
    return(OUT)
  }

  draw_groups <- function(., data, scales, coordinates, ...) {
    GeomRect$draw_groups(data, scales, coordinates, ...)
  }
  guide_geom <- function(.) "polygon"
})

这只是从ggplot2 github复制geom_bar代码,然后切换 x y 引用,在标准笛卡尔协调器中制作水平条形图。

请注意,必须使用position='identity',也可能stat='identity'才能使用此功能。如果您需要使用身份以外的位置,那么您必须对collide function进行eddit才能使其正常工作。

答案 2 :(得分:2)

我一直在尝试做一个水平的条形图,并遇到了我想scales = "free_x"的问题。最后,创建传统(垂直)条形图似乎更容易,旋转文本,这样如果你将头部向左倾斜,它看起来就像你想要的情节。然后,完成绘图后,旋转PDF /图像输出(!)

ggplot(data, aes(x, y)) +
  geom_bar(stat = "identity") +
  facet_grid(var ~ group, scale = "free", space = "free_x", switch = "both") +
  theme(axis.text.y  = element_text(angle=90), axis.text.x = element_text(angle = 90),
                     strip.text.x = element_text(angle = 180))

执行此操作的主要键是switch = "both",它将构面标签移动到另一个轴,以及element_text(angle=90),它可以旋转轴标签和文本。