我很高兴地宣布,ggplot2 2.0.0版本发布了。我知道我曾允诺过它不会有任何更多的更新,但是当我在写ggplot2这本书的第二版本时,我无法阻止我自己去修复一些长期存在的问题。
在ggplot2的所有版本里,这个版本做了至少100次以上的巨大修复和改善。这可能会打破一些现有的代码(尽管我在尽可能的减少破损),但我希望新的特性可以弥补任何短期的麻烦。这篇博客记录了一些重要的变化:
ggplot2现在有一个正式的扩展机制
增加了少量的geoms,并更新了现有的geoms
对默认的外观进行了彻底的调整,因此大多数绘图应该会更好看
面板上有更丰富的标签选项集
对帮助文档进行了大修,只需较少的集成就可以在多个页面切换(看这)
一些老的以及很少使用的功能被弃用了
上面几个变化的详细描述将在下面给出。关于这个版本的所有更改列表请看发行说明
或许这个ggplot2新版本的最大消息就是它有了一个正式的扩展机制。这意味着其他人可以轻易的创建自己的stats,geoms和positions,并放在其他包中使用。即使在ggplot2本身很少做开发的情况下,这样做也会促进ggplot2社区的蓬勃发展。详情请看ggplot2扩展简介
结合这个变化,ggplot2不再使用原型或引用类。相反,我们现在使用ggproto,它是一个专为ggplot2设计的面向对象系统。不同于原型和RC,ggproto支持清除跨包继承,它对可扩展性来说是必要的。新建一个新的面向对象系统通常不是一个正确的解决方案,但我敢肯定它在这是必要的。需要了解更多可以阅读上面的ggplot2扩展简介。
如果你的绘图没有图层画板,ggplot不再抛出错误。相反,它会自动增加geom_blank()
:
ggplot(mpg, aes(cyl, hwy))
geom_count()
(老版本里stat_sum()的别名),在散点图的不同位置处给出点的计数,并且映射出点的大小:
ggplot(mpg, aes(cty, hwy)) + geom_point() ggplot(mpg, aes(cty, hwy)) + geom_count()
geom_curve()
跟geom_segment()
绘制直线的方式一样,绘制曲线:
df <- expand.grid(x = 1:2, y = 1:2) ggplot(df,aes(x, y, xend = x + 0.5, yend = y+ 0.5)) + geom_curve(aes(colour = "curve")) + geom_segment(aes(colour = "segment"))
geom_bar
跟geom_histogram()
的表现形式不一样。跟数据分档不同,它对每个位置的唯一观测值进行计数。
ggplot(mpg, aes(cyl)) + geom_bar() ggplot(mpg, aes(cyl)) + geom_histogram(binwidth = 1)
如果你习惯(坏习惯)于使用geom_histogram()
来创建条形图或者是使用geom_bar()
来创建直方图,那你需要切换回来。
图层面板对参数更加严格――如果你给出的参数不是美学的或者它就不是一个参数,那会得到一个错误。这破坏了少数的geoms/stats通过使用额外的参数在底层进行运算。现在,geom_smooth()
/stat_smooth()
和geom_quantile()
/stat_quantile()
使用method.args
来代替;stat_summary()
,stat_summary_hex()
以及stat_summary2d()
使用fun.args
来代替。这在短期可以会觉得有点痛苦,但从长期来看,这将使它更加容易识别拼写错误和其他错误。
对geom_text()
进行了大的改进,让标记数据更加容易一些。你可以使用nudge_x
和nudge_y
参数在它们的对应点处标上标签。check_overlap = TRUE
可以避免标记数据时重叠(不妨在下面的代码中去掉这个参数看会发生什么):否则,重叠部分就被遗漏掉了。
ggplot(mtcars, aes(wt, mpg, label = rownames(mtcars))) + geom_point() + geom_text(nudge_y = 0.5, check_overlap = TRUE)
geom_label()
跟geom_text()
一样,但是它是在每个标签下面绘制一个圆角矩形:
grid <- expand.grid( x = seq(-pi, pi, length = 50), y = seq(-pi, pi, length = 50) ) %>% mutate(r = x ^ 2 + y ^ 2, z = cos(f ^ 2) * exp(-r / 6)) ggplot(grid, aes(x, y)) + geom_raster(aes(fill = z)) + geom_label(data = data.frame(x = 0, y = 0), label = "Center") + theme(legend.position = "none") + coord_fixed()
注:需要安装加载dplyr
包
aes_()
代替aes_q()
,它类似于dplyr
包以及我最近其他包中的SE函数。它支持公式,因此aes(carat, price)
最简洁的SE版本是现在的aes_(~carat, ~price)
。你可能要在包中使用这种形式,这样可以避免在运行R CMD check
时出现“未定义全局变量”的警告。
ggplot(mpg, aes_(~displ, ~cty)) + geom_point() # Same as ggplot(mpg, aes(displ, cty)) + geom_point()
我对默认外观作了一些调整:
theme_grey()
的默认背景颜色由"grey90"调整为"grey92":这样可以让背景不那么显眼
对标签和标题的可读性做了一些调整。轴标签更暗了一些,图例标题的视觉处理跟轴标签一样了。
默认字体大小由12降到11。你可能会感到很惊讶,为什么对于许多人来说阅读起来已经很困难了却还要把默认字体的设置得更小。其实,RStudio里面有一个bug叫定格在0.99.724,它收缩了所有基于网格图形的文本。我这样做就解决了原先默认值看起来比较大的情况。
scale_size()
现在是映射到area
,而不是半径。如果你还想用旧的方式,那就使用scale_radius()
(不建议用,除非是线的情况下)。
条状图例和矩形图例不再有对角线。代替的是,调整了边界使其可见,并且边界线的粗细跟图中的边框线是一样的。
ggplot(mpg, aes(factor(cyl), fill = drv)) + geom_bar(colour = "black", size = 1) + coord_flip()
geom_point()
用形状19代替了形状16。这在Linux图形设备上看起来好多了(它比老的点略小了些,但这并不明显影响到图形)。你可以在形状21-25之间通过参数stroke
来控制边框线的宽度。
默认的图例分配多行(如果垂直的话)或者多列(如果水平的话)是为了在屏幕上更适合显示。你可以重写guide_legend()
的nrow/ncol
参数
p <- ggplot(mpg, aes(displ,hwy, colour = manufacturer)) + geom_point() + theme(legend.position = "bottom") p # Revert back to previous behaviour p + guides(colour = guide_legend(nrow = 1))
Jean-Olivier Irisson贡献了两个新的主题:theme_void()
意味着完全是空白的。theme_dark()
给出的是黑色背景,这样可以突出颜色。
多亏Lionel Henry的工作,面板标签获得了三个主要的改进:
你可以切换面板标签的位置,使它成为下一个轴
facet_wrap()
支持自定义标签
当有多个变量分面的时候,可以创建联合标签
新的switch
参数允许你将标签切换到近轴显示
data <- transform(mtcars, am = factor(am, levels = 0:1, c("Automatic", "Manual")), gear = factor(gear, levels = 3:5, labels = c("Three", "Four", "Five")) ) ggplot(data, aes(mpg, disp)) + geom_point() + facet_grid(am ~ gear, switch = "both")
当用标签直接来表示坐标轴时,这特别有用。在这种情况下,切换标签可以使图更清晰以及更具可读性。你也可以通过设置strip.background
为element_blank()
来达到中性标签背景的效果:
data <- mtcars %>% mutate( Logarithmic = log(mpg), Inverse = 1 / mpg, Cubic = mpg ^ 3, Original = mpg ) %>% tidyr::gather(transformation, mpg2, Logarithmic:Original) ggplot(data, aes(mpg2, disp)) + geom_point() + facet_wrap(~transformation, scales = "free", switch = "x") + theme(strip.background = element_blank())
注:需要安装和加载tidyr
包
ggplot一个长期存在的问题是facet_wrap()
不支持自定义labellers。labeller是一个自定义标签的函数。现在,你可以把labeller运用到外面板和网格面板上。
ggplot(data, aes(mpg2, disp)) + geom_point() + facet_wrap(~transformation, scales = "free", labeller = "label_value")
当你的面板包含多个变量时,labellers可以更好的支持复合的边界。所有的labellers增加了一个multi_line
参数,它是用来控制每个因子的标签应显示为单行还是多行。
除了label_bquote()
以外,labellers的工作方式是一样的。labeller可以很容易的编写包含面板因子的数学表达式。过去,label_bquote()
仅仅只能对所有的边界和因子指定一个表达式。该因子值的简称是反引号占位符.(x)
。现在,它支持多个因子结合的表达式,你必须对这些变量名进行反引号。另外,你可以对每个边界给出不同的表达式:
my_labeller <- label_bquote( rows = .(am) / alpha, cols = .(vs) ^ .(cyl) ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + facet_grid(am ~ vs + cyl, labeller = my_labeller)
我对文档进行了彻底的修改:
将紧密关联的geoms和stats(如geom_boxplot()
和stat_boxplot()
)记录在同一文件中,以便你在同一个地方可以查看所有的参数。同样的,主题上的变化(像geom_path()
,geom_line()
和geom_step()
)也记录在一块。
我试图减少"..."的使用,以便在一个地方查看所有的文档,而不是在围绕着周围的链接。在某些情况下,为了让你更加明白你能做什么,我对geoms增加了额外的参数。
多亏Bob Rudis,qplot()
在示例中的使用已经大幅减少了。在ggplot2这本书的第二版本,已经删除了qplot()
,取而代之的是ggplot()
。
order
正式被弃用。它从来就没有被使用过,关于它的文档也很少。
qplot()
的参数stat
和position
也不在可用了。qplot()
是专为快速绘图设计,如果你需要指定position
或stat
,用ggplot()
来代替它。
主题设定axis.ticks.margin
已被弃用:现在使用axis.ticks
边界属性
stat_abline()
,stat_hline()
和stat_vline()
已被删除:它们从来都没有跟geoms相匹配的使用过,并且没有被记载过。
show_guide
改名为show.legend
:这更能准确的反映它能做什么(控制图例的外观层),并且使用的是ggplot2其他参数中相同的约定(即“a.names”)。(是的,我知道这样跟函数的命名不一致,但现在改为时已晚了)
对多数geoms进行了统一更名。在未来的一段时间,之前的名称也可以继续使用。不过你应该在新的工作中使用新的名称。
stat_binhex()
,stat_bin2d()
分别更名为stat_bin_hex()
,stat_bin_2d()
。stat_summary2d()
更名为stat_summmary_2d()
,geom_density2d()/stat_density2d()
更名为geom_density_2d()/stat_density_2d()
。
stat_spoke()
就是现在的geom_spoke()
,因为我意识到它就是geom_segment()
的再参数化。
stat_bindot()
已被删除。因为它与geom_dotplot()
太过耦合。如果你正巧使用stat_bindot()
,只要改为geom_dotplot()
即可。
所有不再使用的函数都删除掉了。
本文由雪晴数据网负责翻译整理,原文请参考ggplot 2.0.0,作者Hadleywickham。转载请注明本文链接http://www.xueqing.cc/cms/article/92