[英]ggplot2 Facet Wrap Reorder by y-axis, Not x-axis
我想绘制多面条形图并从最大值到最小值从左到右排序。 我应该能够使用类似于此的代码执行此操作:
library(ggplot2)
ggplot(mpg, aes(reorder(cyl, -hwy), hwy)) +
geom_col() +
facet_wrap(~ manufacturer, scales = "free")
相反,我得到的是x轴排序,恰好是'cyl',从最小值到最大值。 如何按y轴顺序下降,看起来像帕累托图? 它也必须是分面的。 谢谢。
如果我理解你的问题,我们的目标是绘制公路平均英里(该hwy
列)由cyl
每个manufacturer
。 在每个manufacturer
,您希望通过每个cyl
的平均hwy
值来订购x轴( cyl
值)。
为此,我们需要为每个制造商单独创建绘图,然后将它们放在一起。 这是因为对于同一图中的不同面板,我们不能有不同的x轴排序(在这种情况下为cyl
排序)。 (更新:我的观点得到纠正。@ missuse的答案链接到David Robinson编写的函数 ,基于Tyler Rinker的博客文章,改变了刻面图中的x轴标签顺序。)因此,我们将创建一个图表列表和然后把它们放在一起,好像它们被刻面了一样。
library(tidyverse)
library(egg)
因为在实际数据中, hwy
的平均值总是随着cyl
增加而单调递减,我们将为8缸Audis创建一个人为的高hwy
值,仅用于说明:
mpg$hwy[mpg$manufacturer=="audi" & mpg$cyl==8] = 40
现在我们按manufacturer
分割数据,这样我们就可以创建一个单独的图,因此每个制造商都有一个单独的cyl
排序。 我们将使用map
函数迭代制造商。
plot.list = split(mpg, mpg$manufacturer) %>%
map(function(dat) {
# Order cyl by mean(hwy)
dat = dat %>% group_by(manufacturer, cyl) %>%
summarise(hwy = mean(hwy)) %>%
arrange(desc(hwy)) %>%
mutate(cyl = factor(cyl, levels=cyl))
ggplot(dat, aes(cyl, hwy)) +
geom_col() +
facet_wrap(~ manufacturer) +
theme(axis.title=element_blank()) +
expand_limits(y=mpg %>%
group_by(manufacturer,cyl) %>%
mutate(hwy=mean(hwy)) %>%
pull(hwy) %>% max)
})
现在让我们从绘图中删除y轴值和刻度,当我们将这些绘图放在一起时,这些值将不在第一列中:
num_cols = 5
plot.list[-seq(1,length(plot.list), num_cols)] =
lapply(plot.list[-seq(1,length(plot.list), num_cols)], function(p) {
p + theme(axis.text.y=element_blank(),
axis.ticks.y=element_blank())
})
最后,我们列出了这些情节。 来自egg
包装的ggarrange
确保面板都具有相同的宽度(否则由于y轴标签占据的空间,第一列中的面板将比其他面板更窄)。
ggarrange(plots=plot.list, left="Highway MPG", bottom="Cylinders", ncol=num_cols)
请注意, audi
的cyl
值不是递增的顺序,表明我们的重新排序正常工作。
这是一种不同的方法,可以使用这里的两个函数直接在ggplot中执行。 我将使用eipi10的例子:
library(tidyverse)
mpg$hwy[mpg$manufacturer=="audi" & mpg$cyl==8] <- 40
dat <- mpg %>% group_by(manufacturer, cyl) %>%
summarise(hwy = mean(hwy)) %>%
arrange(desc(hwy)) %>%
mutate(cyl = factor(cyl, levels = cyl))
功能:
reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
new_x <- paste(x, within, sep = sep)
stats::reorder(new_x, by, FUN = fun)
}
scale_x_reordered <- function(..., sep = "___") {
reg <- paste0(sep, ".+$")
ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}
情节:
ggplot(dat, aes(reorder_within(cyl, -hwy, manufacturer), y = hwy), hwy) +
geom_col() +
scale_x_reordered() +
facet_wrap(~ manufacturer, scales = "free") +
theme(axis.title=element_blank())
对于升序,你会: reorder_within(cyl, hwy, manufacturer)
没有功能的情节:
ggplot(dat, aes(cyl, y = hwy)) +
geom_col() +
facet_wrap(~ manufacturer, scales = "free") +
theme(axis.title=element_blank())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.