Bokeh 与以往的绘图工具类似,不同之处在于,前面的工具都是以绘制统计图,通常会直接提供专门绘制统计图的函数,但是 Bokeh 中提供的图线模型,是以常见的几何图形或者曲线为主,同时能够用它们绘制常见的统计图。从这点来说,Bokeh 更捉住了数据可视化的未来发展——不局限于统计图范畴。
下面就列举几种图形或曲线的绘制方法(这些方法在官方文档中都有详细说明),读者可以从中体会 Bokeh 的特点。
为了将图形插入到 Jupyter 浏览器中,先执行下述代码:
from bokeh.plotting import output_notebook
output_notebook()
这样做便于调试和学习,而在以后的商业项目中是否如此操作,要看具体要求。
6.2.1 饼图
饼图,是常见的一种统计图,很多工具都提供了专用方法,如 pyecharts 中的 Pie 类,但是在 Bokeh 中没有专门方法或类。
如果把饼图看做“圆形”,倒是 Bokeh 中有相应的基本模型。
from bokeh.plotting import figure, show
fig = figure(plot_width = 500, plot_height = 300)
fig.circle(x = [1, 2, 3, 4, 5],
y = [1, 2, 3, 4, 5],
size = 20,
#angle = 45,
fill_color = 'yellow',
)
show(fig)
输出结果:
fig.circle 方法是以指定的坐标点为圆心,绘制圆(fill_color='white')或者圆面。此方法适合于对各个坐标点以圆(面)表示,但不能用它来画出包含不同比例的扇形图。
跟 fig.circle 类似的还有好几个,如 circle_cross、circle_x、cross 等。下面要演示的 fig.annulus,是专门用来绘制圆环图形的,可以实现类似上图的效果,也可以绘制一个圆环。
fig = figure(plot_width = 500, plot_height = 300)
fig.annulus(x=[3], y=[3], color='green', inner_radius=0.2, outer_radius=0.6)
show(fig)
输出结果:
当然,对于此图而言,如果不想显示坐标轴和坐标网格,可以通过对 figure 函数的参数设置实现。请学习者自行阅读文档并完成。
至此,还没有找到绘制饼图的方法,继续找。
有一个名为 wedge 的方法,从名称上看,wedge 有“楔形”的含义。饼图中的每个扇形图,也就是“楔形”,因此这个方法值得研究—— Python 中的函数、变量、类的命名原则是“望文生义”,寻找实现某个功能的函数 / 方法,一定要将“名称”作为重要线索。
如果把 wedge 列为疑似对象,就应该仔细审查一下它,看看它的参数。或许读者已经敏锐地捕捉到两个以往没有出现的参数 start_angle、end_angle,那就来试一试。
import numpy as np
fig = figure(plot_width = 500, plot_height = 300)
fig.wedge(x=[3,], y=[3,],
radius=80,
start_angle=0,
end_angle=np.pi/2,
radius_units="screen",
color="#2b8cbe")
show(fig)
输出结果:
参数 start_angle 和 end_angle 分别是扇面的起、止半径线段相对水平方向的角度,并且默认是逆时针旋转。
这里绘制了一个扇形,按理说,能绘制一个,就能绘制另外一个,这样组合而成,就是可以分别用不同扇形表示不同比例了。
# 定义每个扇形的起止半径相对水平线的角度
percents = [0, 0.3, 0.4, 0.6, 0.9, 1]
starts = [p*2*np.pi for p in percents[:-1]]
ends = [p*2*np.pi for p in percents[1:]]
# 每个扇形的色彩
colors = ["red", "green", "blue", "orange", "yellow"]
fig = figure(title='Pie Chart', x_range=(-1,1), y_range=(-1,1))
fig.wedge(x=0, y=0, radius=1, start_angle=starts, end_angle=ends, color=colors)
show(fig)
输出结果:
此图,就是我们所要的饼图。当然,如果要在上面标示有关说明,可以通过其他方式进行。原理上来说,这样就实现了饼图。
看到这里,肯定会觉得用 Bokeh 绘制饼图太麻烦了。因此,就不要用 Bokeh 绘制饼图了,用 pyecharts 吧。这说明,不同工具有不同的优势,有不同的主攻方向。就如同吃饭用具一样,筷子是能做不少事情,但是并不是什么地方都能做得最好。因此,有必要多学一些工具——这也是本课的目的,才能临阵不乱,从容选择最适合的。
6.2.2 多边形
在 Bokeh 中不缺乏绘制多边形的方法,如不规则多边形、四边形、三角形等。
先看比较简单的三角形,而且是正三角形。
from bokeh.plotting import figure, show
fig = figure(plot_width=300, plot_height=300)
fig.triangle(x=[3], y=[3], size=[100],
color="#666666", line_width=2)
show(fig)
输出结果:
虽然这样绘制了正三角形,其实,fig.triangle 是标记坐标点的符号,跟前面用过的 fig.circle 等是一样的,只不过在上面的例子中只给了一个点 [3, 3] 罢了,如果是下面这样,就熟悉了。
from bokeh.plotting import figure, show
fig = figure(plot_width=300, plot_height=300)
fig.triangle(x=[1, 2, 3], y=[1, 2, 3], size=[10, 30, 20],
color="#666666", line_width=2)
fig.line(x=[1,2,3], y=[1,2,3])
show(fig)
输出结果:
除了绘制正三角形(符号)之外,还有绘制倒三角形的函数 inverted_triangle,使用方法与上述相同。
如果要自定义绘制图形,可以使用 patch 方法。
from bokeh.plotting import figure, show
p = figure(plot_width=300, plot_height=300)
p.patch(x=[1, 3, 2], y=[1, 2, 3], color="#090909")
show(p)
输出结果:
这里得到了一个锐角三角形,三角形的三个顶点坐标分别是 (1, 1)、(3, 2)、(2, 3)。p.patch 方法的参数 x、y 分别对象三角形顶点坐标的 X 轴和 Y 轴的值。与此类似,如果确定了平面直角坐标系中任意一个多边形的各个顶点坐标,就可以绘制出相应的多边形,如下所示。
p = figure(plot_width=300, plot_height=300)
p.patch(x=[1, 1, 1.5, 3, 2.5], y=[1, 2, 2, 3,2], color="red")
show(p)
输出结果:
与 patch 类似的另外一个方法名为 patches,它是复数形式,我们推测是不是可以绘制多个图形。
正解!
p = figure(plot_width=300, plot_height=300)
p.patches(xs=[[1,1,3],[1,3,5,3]],
ys=[[1,2,1],[2,2,4,4]],
color=["gray", "#010199"])
show(p)
输出结果:
请仔细观察 p.patches 方法的参数,跟前面的 p.patch 有所不同,这里使用的是 xs、ys,意即可以通过这两个参数向 p.patches 提供多个不同多边形的顶点。注意观察上述代码,参数的值是嵌套列表。
虽然 patch 和 patches 能够绘制任何多边形,但是某些特殊多边形,因其常用,Bokeh 又提供了单独的方法,比如上面的正三角形,还有下面要演示的矩形。
plot = figure(plot_width=300, plot_height=300)
plot.quad(top=[2, 3, 4], bottom=[1, 2, 3], left=[1, 2, 3],
right=[1.2, 2.5, 3.7], color="#B3DE69")
show(plot)
在 quad 方法中,参数 top、bottom、right、left 分别为该矩形的“上、下、右、左”的边界位置。例如 top=[2, 3, 4],其含义是:
- 第一个矩形的上边界是 y=2 的直线;
- 第二个矩形的上边界是 y=3 的直线;
- 第三个矩形的上边界是 y=4 的直线。
如此,通过设置每个矩形的四边界限(分界“线”),最终确定了一个矩形。
quad 方法除了可以绘制如上面那样的矩形之外,还有另外一个用途——Bokeh 必须如此,那就是绘制表示数据分布的直方图——再次提醒,直方图和柱形图是完全不同的。前面介绍的其他制图工具,有的提供了专门绘制直方图的方法(函数),例如 Seaborn 中的 sns.distplot。但是 Bokeh 中没有专门函数,不得不使用 quad 实现直方图。
网友评论