我想制作一个条形图,其中一个值比所有其他值大得多。有没有一种不连续的y轴方法?我的数据如下:
df <- data.frame(a = c(1,2,3,500), b = c('a1', 'a2','a3', 'a4'))
p <- ggplot(data = df, aes(x = b, y = a)) + geom_bar()
p <- p + opts(axis.text.x=theme_text(angle= 90, hjust=1)) + coord_flip()
p
有没有办法可以让我的轴从1到10,然后是490 - 500?我想不出任何其他绘制数据的方式(除了转换它,我不想做)
8年后,上面的代码需要修改为与ggplot2
的3.1.1版一起使用才能创建相同的图表:
library(ggplot2)
ggplot(df) +
aes(x = b, y = a) +
geom_col() +
coord_flip()
答案 0 :(得分:44)
如其他地方所述,这不是ggplot2
能够很好地处理的事情,因为断轴通常被认为是有问题的。
其他策略通常被认为是解决此问题的更好方法。布莱恩提到了一些(分面,两个关注不同价值观的情节)。人们经常忽略的另一个选择,特别是对于条形图,是制作表:
查看实际值,500不会掩盖其他值的差异!出于某种原因,表格作为可视化技术的数据并没有得到足够的尊重。您可能会反对您的数据有很多很多类别,这些类别在表格中变得难以处理。如果是这样,你的条形图可能会有太多的条形图也是合理的。
我并不是在争论表所有的时间。但如果您制作的酒吧条形图比较少,那么它们绝对值得考虑。如果你正在制作大量酒吧的条形图,你可能需要重新考虑一下。
最后,axis.break
包中还有plotrix
函数实现了断轴。但是,根据我收集的内容,您必须手动指定轴标签和位置。
答案 1 :(得分:26)
不,不使用ggplot。请参阅http://groups.google.com/group/ggplot2/browse_thread/thread/8d2acbfc59d2f247主题中的讨论,其中Hadley解释了为什么它不可能,但提供了建议的替代方案(分面图,一个包含所有数据,一个在特定区域放大)。
答案 2 :(得分:21)
不使用ggplot,但使用plotrix,您可以轻松地执行此操作:
library(plotrix)
gap.barplot(df$a, gap=c(5,495),horiz=T)
答案 3 :(得分:15)
不,不幸的是
恐惧是允许不连续的轴会导致观众的欺骗。但是,有些情况下不具有不连续轴会导致失真。
例如,如果轴被截断,但通常位于某个区间内(例如[0,1]),则观众可能不会注意到截断并对数据做出扭曲的结论。在这种情况下,显式的不连续轴将更合适和透明。
比较
答案 4 :(得分:1)
我怀疑R中有什么现成的,但您可以将数据显示为一系列3D部分立方体。 500仅为5 * 10 * 10,因此它可以很好地扩展。确切的值可以是标签。
这可能只应在必须出于某种原因的图形表示时使用。
答案 5 :(得分:1)
八年后,ggforce
软件包提供了facet_zoom()
扩展名,它是Hadley Wickham's suggestion的一种实现,以显示两个图(如Brian Diggs' answer中所述)。
library(ggforce)
ggplot(df) +
aes(x = b, y = a) +
geom_col() +
facet_zoom(ylim = c(0, 10))
不幸的是,当前ggforce
的0.2.2版本引发了coord_flip()
的错误,因此只能显示竖线。
缩放的构面显示较小值的变化,但仍包含较大的-现在已裁剪-a4
条。 zoom.data
参数控制哪些值显示在缩放的构面中:
library(ggforce)
ggplot(df) +
aes(x = b, y = a) +
geom_col() +
facet_zoom(ylim = c(0, 10), zoom.data = ifelse(a <= 10, NA, FALSE))
我认为更适合显示两个情节-其中之一 数据,只是其中一个较小的值。
此代码创建了两个图
library(ggplot2)
g1 <- ggplot(df) +
aes(x = b, y = a) +
geom_col() +
coord_flip()
g2 <- ggplot(df) +
aes(x = b, y = a) +
geom_col() +
coord_flip() +
ylim(NA, 10)
可以通过以下方式组合成一个图
cowplot::plot_grid(g1, g2) # or ggpubr::ggarrange(g1, g2)
或
gridExtra::grid.arrange(g1, g2) # or egg::ggarrange(g1, g2)
in a comment by Chase和his answer的布莱恩·迪格斯(Brian Diggs)都提出了这个建议,他解释了哈德利的使用建议。
多面图,一个包含所有数据,一个放大到特定区域
但到目前为止,此方法尚未提供任何代码。
由于没有简单的方法可以分别缩放构面(例如,参见related question),因此需要对数据进行操作:
library(dplyr)
library(ggplot2)
ggplot() +
aes(x = b, y = a) +
geom_col(data = df %>% mutate(subset = "all")) +
geom_col(data = df %>% filter(a <= 10) %>% mutate(subset = "small")) +
coord_flip() +
facet_wrap(~ subset, scales = "free_x")
答案 6 :(得分:1)
JörgSteinkamp使用facet_grid提供了clever ggplot solution。简化了,是这样的:
library("tidyverse")
df <- data.frame(myLetter=LETTERS[1:4], myValue=runif(12) + rep(c(4,0,0),2)) # cluster a few values well above 1
df$myFacet <- df$myValue > 3
(ggplot(df, aes(y=myLetter, x=myValue))
+ geom_point()
+ facet_grid(. ~ myFacet, scales="free", space="free")
+ scale_x_continuous(breaks = seq(0, 5, .25)) # this gives both facets equal interval spacing.
+ theme(strip.text.x = element_blank()) # get rid of the facet labels
)
答案 7 :(得分:0)
一种策略是更改轴以绘制对数刻度。这样,您就可以将较高的指数值减少10倍