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?我想不出任何其他方式来绘制数据(除了转换数据外,我不想做)
[编辑2019-05-06]:
8年后,需要对上述代码进行修改以与
ggplot2
的3.1.1版本一起使用,以创建相同的图表:library(ggplot2)
ggplot(df) +
aes(x = b, y = a) +
geom_col() +
coord_flip()
#1 楼
正如其他地方所指出的那样,ggplot2
不能很好地处理此问题,因为通常认为断轴是有问题的。其他策略通常被认为是对此问题的更好解决方案。布赖恩(Brian)提到了一些(构面,两张图关注不同的值集)。人们经常忽略的另一个选择,尤其是对于条形图,是制作一张桌子:
看看实际值,500并不能掩盖差异在其他价值观!由于某种原因,表作为一种可视化技术没有得到足够的重视。您可能会反对您的数据具有许多类别,这些类别在表中变得笨拙。如果是这样,您的条形图也可能会包含太多条形图,以至于也无法理解。
我并不是一直在争辩表格。但是,如果您要制作条形图相对较少的条形图,则绝对是要考虑的事情。而且,如果要用大量的条形图制作条形图,则无论如何都可能需要重新考虑。
最后,
axis.break
软件包中还有plotrix
函数,该函数实现断轴。但是,根据我的收集,您必须手动指定轴标签并自行定位。评论
乔兰,我对于使用这种情节确实有百感交集。您是正确的-表格可能是显示此内容的最佳方法。
– djq
2011年8月25日在18:13
@celenius-我不是要宣扬布道,也不是想骂你。我只是觉得桌子没有得到太多的爱,有时我对此感到厌烦。 ;)
– joran
2011年8月25日在18:15
@joran,我同意对于此特定数据,表格是最佳表示形式(如果只给出如何最好地表示的话,我会建议这样做)。在我的回答中,我过于专注于确切的问题,以至于无法回答应该提出的更广泛的问题。
–布赖恩·迪格斯(Brian Diggs)
11年8月25日在19:03
#2 楼
不,不使用ggplot。请参阅该线程中的讨论,网址为http://groups.google.com/group/ggplot2/browse_thread/thread/8d2acbfc59d2f247,其中Hadley解释了为什么不可能,但给出了建议的替代方法(多面图,一个包含所有数据的图,一个放大特定区域。#3 楼
不是使用ggplot,而是使用plotrix,您可以轻松地做到这一点:library(plotrix)
gap.barplot(df$a, gap=c(5,495),horiz=T)
#4 楼
八年后,ggforce
软件包提供了facet_zoom()
扩展名,该扩展名是Hadley Wickham建议显示两个图的建议的实现(如Brian Diggs的回答所述)。 > library(ggforce)
ggplot(df) +
aes(x = b, y = a) +
geom_col() +
facet_zoom(ylim = c(0, 10))
不幸的是,当前版本0.2.2的
ggforce
引发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))
两个图
Hadley Wickham建议
我认为更适合显示两个图-一个是所有
数据,另一个是较小的值。
此代码创建了两个图
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)
两个方面
在蔡斯(Chase)和布莱恩·迪格斯(Brian Diggs)的回答中,他解释了哈德利关于使用多面图的建议,其中一面包含所有数据,一面放大了特定区域
,但到目前为止,此方法尚未提供任何代码。
由于没有简单的方法可以分别缩放构面(例如,请参阅相关问题),因此需要操纵:
q4312 078q
评论
facet_zoom(),geom_col()和coord_flip()的错误已报告到github.com/thomasp85/ggforce/issues/143。
– Uwe
19年5月6日在9:19
谢谢,我真的很喜欢ggforce facet zoom功能!您是否知道是否可以放大两个范围,在图的每一侧一个?还是只有一条垂直线(仅包含y轴),并且在任一侧都有一个图,并且在两个不同的y值范围内绘制图?
– charlesdarwin
19年11月10日在20:57
#5 楼
不,不幸的是,担心的是,允许不连续的轴会导致观众的欺骗。但是,在某些情况下,轴不连续会导致变形。
例如,如果轴被截断了,但通常位于某个间隔内(例如[0,1]),则听众可能不会注意到截断并得出关于数据的错误结论。在这种情况下,显式的不连续轴会更合适且更透明。
比较:
#6 楼
我怀疑R中是否有现成的东西,但是您可以将数据显示为一系列3D局部立方体。 500只有5 * 10 * 10,因此可以很好地缩放。确切的值可以是标签。仅当出于某种原因必须使用图形表示时,才应使用此功能。
#7 楼
JörgSteinkamp使用facet_grid提供了一个聪明的ggplot解决方案。简化后,它是这样的: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
)
评论
有没有一种方法可以控制左右面板的比例?
–蔡Cai
12月14日下午16:13
#8 楼
一种策略是更改轴以绘制对数刻度。这样,您就可以将指数级较高的值减少10倍。评论
对于某些图形来说,这是一个不错的选择,但对于从0开始的条形图,它不能很好地工作。
–格雷戈·托马斯(Gregor Thomas)
19年8月29日在15:48
评论
我不认为您可以在ggplot2中引入中断。另一种选择是使用对数刻度,这将使图形更易于阅读。我意识到这将使在对数刻度上更容易阅读,但是我不想以这种方式显示信息,因为在转换时隐藏的小值之间会有很大的差异。
关于facet_wrap()与scales =“ free_x”
的组合怎么办?
也可以通过自定义转换来解决此问题...一会儿我会写一个答案