ggplot2:在每个方面从最高到最低重新排序条
ggplot2: reorder bars from highest to lowest in each facet
在下面的 df
中,我想在每个方面[=17= 中从最高到最低重新排列条 ]
我试过了
df <- df %>% tidyr::gather("var", "value", 2:4)
ggplot(df, aes (x = reorder(id, -value), y = value, fill = id))+
geom_bar(stat="identity")+facet_wrap(~var, ncol =3)
它给了我
它没有在每个方面从最高到最低对条形进行排序。
我想出了另一种方法来获得我想要的东西。我必须一次绘制每个变量,然后使用 grid.arrange()
组合所有图
#I got this function from @eipi10's answer
#
#Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot) {
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
p1 <- ggplot(df[df$var== "A", ], aes (x = reorder(id, -value), y = value, fill = id))+
geom_bar(stat="identity") + facet_wrap(~var, ncol =3)
fin_legend <- g_legend(p1)
p1 <- p1 + guides(fill= F)
p2 <- ggplot(df[df$var== "B", ], aes (x = reorder(id, -value), y = value, fill = id))+
geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE)
p3 <- ggplot(df[df$var== "C", ], aes (x = reorder(id, -value), y = value, fill = id))+
geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE)
grid.arrange(p1, p2, p3, fin_legend, ncol =4, widths = c(1.5, 1.5, 1.5, 0.5))
结果就是我想要的
我想知道是否有一种直接的方法可以帮助我在所有方面从最高到最低对条形进行排序,而不必分别绘制每个变量然后将它们组合起来。任何建议将不胜感激。
数据
df <- read.table(text = c("
id A B C
site1 10 15 20
site2 20 10 30
site3 30 20 25
site4 40 35 40
site5 50 30 35"), header = T)
如果您愿意丢失 X 轴标签,您可以使用实际的 y 值作为 x 美学,然后在每个方面删除未使用的因子水平:
ggplot(df, aes (x = factor(-value), y = value, fill = id))+
geom_bar(stat="identity", na.rm = TRUE)+
facet_wrap(~var, ncol =3, scales = "free_x", drop = TRUE) +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
)
结果:
x 轴标签的丢失在这里可能还不算太糟糕,因为您仍然可以继续使用颜色(而且 x 轴无论如何都很混乱,因为它在各个方面都不一致)。
下面的方法使用专门为 facet_wrap()
的 x 轴准备的变量,但使用 scale_x_discrete()
的 labels
参数来显示正确的 x 轴标签:
准备数据
我比较流利data.table
,所以这里用这个。随意使用您喜欢的任何包进行数据操作。
编辑:删除了第二个虚拟变量,只需要 ord
library(data.table)
# reshape from wide to long
molten <- melt(setDT(df), id.vars = "id")
# create dummy var which reflects order when sorted alphabetically
molten[, ord := sprintf("%02i", frank(molten, variable, -value, ties.method = "first"))]
molten
# id variable value ord
# 1: site1 A 10 05
# 2: site2 A 20 04
# 3: site3 A 30 03
# 4: site4 A 40 02
# 5: site5 A 50 01
# 6: site1 B 15 09
# 7: site2 B 10 10
# 8: site3 B 20 08
# 9: site4 B 35 06
#10: site5 B 30 07
#11: site1 C 20 15
#12: site2 C 30 13
#13: site3 C 25 14
#14: site4 C 40 11
#15: site5 C 35 12
创建地块
library(ggplot2)
# `ord` is plotted on x-axis instead of `id`
ggplot(molten, aes(x = ord, y = value, fill = id)) +
# geom_col() is replacement for geom_bar(stat = "identity")
geom_col() +
# independent x-axis scale in each facet,
# drop absent factor levels (not the case here)
facet_wrap(~ variable, scales = "free_x", drop = TRUE) +
# use named character vector to replace x-axis labels
scale_x_discrete(labels = molten[, setNames(as.character(id), ord)]) +
# replace x-axis title
xlab("id")
数据
df <- read.table(text = "
id A B C
site1 10 15 20
site2 20 10 30
site3 30 20 25
site4 40 35 40
site5 50 30 35", header = T)
在下面的 我试过了 它给了我
它没有在每个方面从最高到最低对条形进行排序。 我想出了另一种方法来获得我想要的东西。我必须一次绘制每个变量,然后使用 结果就是我想要的
我想知道是否有一种直接的方法可以帮助我在所有方面从最高到最低对条形进行排序,而不必分别绘制每个变量然后将它们组合起来。任何建议将不胜感激。 数据df
中,我想在每个方面[=17= 中从最高到最低重新排列条 ]
df <- df %>% tidyr::gather("var", "value", 2:4)
ggplot(df, aes (x = reorder(id, -value), y = value, fill = id))+
geom_bar(stat="identity")+facet_wrap(~var, ncol =3)
grid.arrange()
#I got this function from @eipi10's answer
#
df <- read.table(text = c("
id A B C
site1 10 15 20
site2 20 10 30
site3 30 20 25
site4 40 35 40
site5 50 30 35"), header = T)
如果您愿意丢失 X 轴标签,您可以使用实际的 y 值作为 x 美学,然后在每个方面删除未使用的因子水平:
ggplot(df, aes (x = factor(-value), y = value, fill = id))+
geom_bar(stat="identity", na.rm = TRUE)+
facet_wrap(~var, ncol =3, scales = "free_x", drop = TRUE) +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
)
结果:
x 轴标签的丢失在这里可能还不算太糟糕,因为您仍然可以继续使用颜色(而且 x 轴无论如何都很混乱,因为它在各个方面都不一致)。
下面的方法使用专门为 facet_wrap()
的 x 轴准备的变量,但使用 scale_x_discrete()
的 labels
参数来显示正确的 x 轴标签:
准备数据
我比较流利data.table
,所以这里用这个。随意使用您喜欢的任何包进行数据操作。
编辑:删除了第二个虚拟变量,只需要 ord
library(data.table)
# reshape from wide to long
molten <- melt(setDT(df), id.vars = "id")
# create dummy var which reflects order when sorted alphabetically
molten[, ord := sprintf("%02i", frank(molten, variable, -value, ties.method = "first"))]
molten
# id variable value ord
# 1: site1 A 10 05
# 2: site2 A 20 04
# 3: site3 A 30 03
# 4: site4 A 40 02
# 5: site5 A 50 01
# 6: site1 B 15 09
# 7: site2 B 10 10
# 8: site3 B 20 08
# 9: site4 B 35 06
#10: site5 B 30 07
#11: site1 C 20 15
#12: site2 C 30 13
#13: site3 C 25 14
#14: site4 C 40 11
#15: site5 C 35 12
创建地块
library(ggplot2)
# `ord` is plotted on x-axis instead of `id`
ggplot(molten, aes(x = ord, y = value, fill = id)) +
# geom_col() is replacement for geom_bar(stat = "identity")
geom_col() +
# independent x-axis scale in each facet,
# drop absent factor levels (not the case here)
facet_wrap(~ variable, scales = "free_x", drop = TRUE) +
# use named character vector to replace x-axis labels
scale_x_discrete(labels = molten[, setNames(as.character(id), ord)]) +
# replace x-axis title
xlab("id")
数据
df <- read.table(text = "
id A B C
site1 10 15 20
site2 20 10 30
site3 30 20 25
site4 40 35 40
site5 50 30 35", header = T)