Bokeh是一个Python可视化库,它可以创建基于web的交互可视化,并在浏览器上进行展示。Bokeh在Scala、Julia和R等语言中都有接口。今天介绍Bokeh在R中的接口rbokeh包。
虽然rbokeh的功能不如Bokeh全面,还是可以作为R可视化的一种补充选择(比如说,我是因为需要画元素周期表才发现这个包的)。
Bokeh图像是这样构建的,先初始化一个figure(),然后通过Bokeh中可用的各种glyph(图形符号)在图像上添加层。数据输入通常是x和y的形式,指定方式非常灵活。
glyphs 可以根据所需的用途呈现多种形状:圆形(circles),线条(lines) ,小块(patches),条形(bars),弧形(arcs)等。
我们从一个绘制散点图的小例子开始对rbokeh进行介绍。mpg是ggplot2包中的一个数据集,其中包含了38种车型的观测数据对变量displ(引擎大小)和hwy(燃油效率):
图1
我们按汽车类别(class)指定颜色的,自动地创建了图例,并根据默认颜色方案对点进行着色。可以将鼠标悬停在点上,以查看相应的文字内容。还可以使用其他交互组件(如平移和缩放)进行操作。
下面讨论rbokeh的作图方法。
rbokeh中的图形是通过叫做glyph的分层图形元素创建的,这种方式非常类似于ggplot2中使用的几何对象geom。
首先,调用figure()对图形进行初始化,记初始化的图形为p。figure()有一些参数,如长(width)、宽(height)以及坐标轴(axe)。然后,就可以在初始化的图形上一层层地添加各种图形元素。这种作图思路与ggplot2很接近。
所有的图层函数都以ly_前缀开始,完整的函数列表参见文末的表1。图层函数的第一个参数是要修正的图形p(可以使用管道运算符将p传递到这个函数)。接下来,大多数的图层函数确参数x和y,确定所指定的图形元素glyph的位置,接下来的参数对应glyph的属性。所有的图层函数都返回一个图层对象,可以把它传递给接下来的图层函数。
回到文章开头的例子。对gglot2包中的数据集mpg,我们想展示其中变量displ和hwy的散点图。
首先,安装并载入包:
###安装并载入包
install.packages("rbokeh")
library(rbokeh)
library(tidyverse)
然后,初始化图形:
p<-figure(width = 800, height = 600)
将p传递给绘制散点的图层函数ly_points():
h<-p%>%
ly_points(x=displ,y=hwy,data=mpg)
h
可以看到:
图2
如果不熟悉管道运算符,上面的代码可以这样写 :
p<-figure(width = 800, height = 600)
h<-ly_points(p,x=displ,y=hwy,data=mpg)
h
可以得到一样的图形。
在上面的例子中,通过data参数将数据框mpg传递给了绘图函数。数据的指定也可以通过这样的方式完成:x=mpg$displ,y=mpg$hwy
。
数据指定还有一些方式,比如:
p<-figure(width = 800, height = 600)%>%
ly_points(displ,data=mpg)
p
在这里,我们只对图层函数传递了一个向量。此时,x轴会表示观测的序号,y轴对应这个向量的取值:
图3
再或者:
p<-figure(width = 800, height = 600)%>%
ly_points(mpg)
p
这里,我们将整个数据框mpg作为向量传递给图层函数,那么x轴对应mpg的第一个变量,y轴对应mpg的第二个变量。
(图略)
下面讨论交互可视化中的悬停能力(hover)。用于渲染形状而不是线条的图层函数都有一个hover参数。这个参数可以是与x和y有同样长度的数据框,也可以是data参数中的名称向量。指定hover参数之后,就会激活悬停工具,当悬停在图中某一个点上时,就会显示该点的指定变量的取值:
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,
hover=list(displ,hwy))
p
图4
如果不添加hover参数,得到的就是一幅展示在浏览器中的非交互的图形。
对每一个层,我们可以明确地指定图形属性,如大小、颜色、形状等。比如,指定上图中点的颜色和大小:
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,size=15,
color="red",hover=list(displ,hwy))
p
(图略)
或者,我们自定义一个从橙色到红色的调色板,并指定点的大小与displ变量的取值成比例:
n <- nrow(mpg)
ramp <- colorRampPalette(c("orange", "red"))(n)
p<-figure(width = 800, height = 600) %>%
ly_points(x=displ,y=hwy,data=mpg, color = ramp,size=5*round(displ))
p
图5
每一个层函数都有线属性或者线和填充属性(文本层ly_text除外)。从层函数的名称可以看出glyph属于哪一类,并且列在函数引用当中。
上面绘制散点图的例子中,散点同时具有线属性(圆的轮廓)和填充属性(圆内的区域):
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,line_color="black",
fill_color="red",fill_alpha=0.3)
p
图6
color和alpha(透明度)这两个参数可以同时处理线与填充属性。具体表现取决于绘制的glyph具有什么样的属性,比如点就同时具有线和填充属性。当指定了color的时候,意味着同时指定了线和填充的颜色,同时填充的alpha被指定为0.5。
不同图层函数的大多数属性从函数引用中就可以看出来,但有些属性还是值得专门说明。其中之一就是ly_points()中的glyph属性。它类似于R函数points()中的参数pch(点的类型)。
glyph所有可用的类型如下:
point_types()
图7
其中第4行和第5行那些有名字的glyphs在Bokeh中称为“markers”,当参数color指定为“blue”时,这些markers以默认渲染的方式呈现。
我们可以看下面的例子,修改现有的散点图,对散点采用符号3:
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,glyph=3,
hover=list(displ,hwy))
p
(图略)
与ly_points()中的glyph属性类似,在ly_lines()函数中有用来表示线条类型的type参数。它的功能就是R函数lines()中的lty参数。
比如,我们在散点图上添加拟合线,其中lowess运用的是局部加权回归,lm运用的是线性回归:
z <- lm(hwy ~ displ, data = mpg)
p <- figure(width = 800, height = 600) %>%
ly_points(x=displ,y=hwy,data=mpg, hover = mpg) %>%
ly_lines(lowess(mpg$displ,mpg$hwy), legend = "lowess") %>%
ly_abline(z, type =2, legend = "lm")
p
图8
type参数共有6种取值(1-6),分别对应solid、 dashed、 dotted、dotdash、longdash、twodash(实心、虚线、点划线、点划线、长划线、双划线)。
我们常常希望按照数据的其他性质来控制glyph属性的表现。此时,rbokeh包借鉴了ggplot2的qplot()中的思想,允许指定变量以映射到不同的属性。
下面的例子,根据mpg数据集中表示汽车类型的变量class绘制点的颜色和类型:
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,
color=class,glyph=class)
p
得到的就是文章开头的图形。
rbokeh也可以映射连续变量,这种情况下,这个连续变量会被离散化成若干区间。比如,我们使用mpg中的另一个变量cty来确定散点的颜色:
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,color=cty)
p
图9
在将属性映射到数据中的变量时,可以自动获得图例。当然,我们也可以创建图例,添加到图形中的每个图层都可以有一个相应的图例。只有在不对属性进行映射时,legend参数才起作用。在图例中显示的图形元素将会根据图层指定的属性自动创建。比如,在拟合的例子中,对不同的拟合线建立图例:
z <- lm(hwy ~ displ, data = mpg)
p <- figure() %>%
ly_points(x=displ,y=hwy,data=mpg,legend="data") %>%
ly_lines(lowess(mpg$displ,mpg$hwy), legend = "lowess") %>%
ly_abline(z, type =2, legend = "lm")
p
图10
Bokeh允许指定数值型、分类型以及日期/时间型的坐标轴。对于数值型的情况下,还可以指定对数尺度的坐标轴。
在坐标轴层,可以指定多种刻度格式参数。细节可以参考x_axis或y_axis的帮助文档。
对于不同的交互类型,Bokeh提供了许多工具。要将这些工具添加到图形上,可以通过figure()的tools参数,此时要提供工具的名称;也可以通过各种以tool_开头的函数,可以参考帮助文件。
下面的例子,添加了tool_box_select()和tool_lasso_select():
p<-figure(width = 800, height = 600)%>%
ly_points(x=displ,y=hwy,data=mpg,color="red")%>%
tool_box_select()%>%
tool_lasso_select()
p
图11
可以看到图形右上方的工具条中多出了套索和方块的形状,可以使用这些工具选择图中的某个区域。
有一些图层函数可以添加具有统计意义的图形元素,比如ly_boxplot(盒形图)、ly_hist(直方图)、ly_density(概率密度图)。
比如,绘制mpg数据集中displ变量的直方图并添加概率密度曲线:
h<-figure(width = 800, height = 600)%>%
ly_hist(displ,data=mpg,breaks=40,freq=FALSE)%>%
ly_density(displ,data=mpg)
h
图12
表1:图层函数ly_()
--------------------------------------------------------
ly_annular_wedge 添加“环形小块”图层
ly_annulus 添加环形图层
ly_arc 添加弧形图层
ly_bezier 添加贝塞尔曲线
ly_crect 添加定中心的矩形
ly_image 添加一个“图像”层
ly_image_url 添加来自url的图像
ly_lines 添加线条
ly_multi_line 绘制多条线
ly_oval 添加椭圆形
ly_patch 在图像上添加小块
ly_points 添加点
ly_polygons 添加多边形
ly_quadratic 添加二次曲线
ly_ray 添加射线
ly_rect 添加矩形
ly_segments 添加线段
ly_text 添加文本
ly_wedge 添加楔形
ly_quantile 绘制分位数
ly_density 绘制核密度估计曲线
ly_hist 绘制直方图
ly_hexbin 添加六边形
ly_boxplot 绘制盒形图
ly_abline 绘制直线
ly_contour 绘制等高线
ly_curve 绘制曲线
ly_map 绘制地图
ly_bar 绘制条形图