导读:柱状图是当前应用最广泛的图表之一,你几乎每天都可以在电子产品上看到它。它有哪些分类?可以展示哪些数据关系?怎样用Python绘制?本文带你逐一了解。

作者:屈希峰,资深Python工程师,知乎多个专栏作者

来源:大数据DT(ID:hzdashuju)

01 概述

柱状图(Histogram)是一种以长方形的长度为变量的表达图形的统计报告图,由一系列高度不等的纵向条纹表示数据分布的情况,用来比较两个或两个以上的价值(不同时间或者不同条件),只有一个变量,通常用于较小的数据集分析。

柱状图也可横向排列,或用多维方式表达。其主要用于数据统计与分析,早期主要用于数学统计学科中,用柱状图表示数码相机的曝光值,到现代使用已经比较广泛,比如现代的电子产品和一些软件的分析测试,如电脑、数码相机的显示器和Photoshop上都能看到相应的柱状图。

1. 基础柱状图

基础柱状图经常用来对比数值的大小,使用范围非常广泛,例如科比在不同赛季的得分、不同游戏App下载量、不同时期手机端综合搜索用户规模等,图2-33显示不同种类水果的销量。

▲图2-33 基本柱状图

需要注意的是,分类太多不适合使用竖向柱状图,如图2-34所示。

▲图2-34 竖向柱状图

此时,需要用到横向柱状图,如图2-35所示。

▲图2-35 横向柱状图

2. 分组柱状图

分组柱状图,又叫聚合柱状图。当使用者需要在同一个轴上显示各个分类下不同的分组时,需要用到分组柱状图。

跟柱状图类似,使用柱子的高度来映射和对比数据值。每个分组中的柱子使用不同颜色或者相同颜色不同透明的方式区别各个分类,各个分组之间需要保持间隔。

分组柱状图经常用于不同组间数据的比较,这些组都包含了相同分类的数据。例如,展示改革开放以来城镇与农村人口的变化,不同游戏公司的休闲、益智、格斗类App的下载量对比等。图2-36对比了2015—2017年间不同水果的销量。

▲图2-36 分组柱状图

3. 堆叠柱状图

与并排显示分类的分组柱状图不同,堆叠柱状图将每个柱子进行分割以显示相同类型下各个数据的大小情况。它可以形象地展示一个大分类包含的每个小分类的数据,以及各个小分类的占比,显示的是单个项目与整体之间的关系。我们将堆叠柱状图分为两种类型:

1)一般的堆叠柱状图:每一根柱子上的值分别代表不同的数据大小,各层的数据总和代表整根柱子的高度。非常适用于比较每个分组的数据总量。

2)百分比的堆叠柱状图:柱子的各个层代表的是该类别数据占该分组总体数据的百分比。

堆叠柱状图的一个缺点是当柱子上的堆叠太多时会导致数据很难区分对比,同时很难对比不同分类下相同维度的数据,因为它们不是按照同一基准线对齐的。

图2-37是显示2015—2017年间不同水果的累计数量。

▲图2-37 堆叠柱状图

4. 双向柱状图

双向柱状图,又名正负条形图,使用正向和反向的柱子显示类别之间的数值比较。其中分类轴表示需要对比的分类维度,连续轴代表相应的数值,分为两种情况,一种是正向刻度值与反向刻度值完全对称,另一种是正向刻度值与反向刻度值反向对称,即互为相反数。

图2-38是显示2015—2017年间不同水果的进出口数量。

▲图2-38 双向柱状图

5. 瀑布图

瀑布图是由麦肯锡顾问公司所独创的图表类型,因为形似瀑布流水而称之为瀑布图(Waterfall Plot)。此种图表采用绝对值与相对值结合的方式,适用于表达数个特定数值之间的数量变化关系。图2-39显示历年短跑冠军的时间跨度,由此可以看出人类体能极限越来越高了。

▲图2-39 瀑布图

接下来,我们看看如何用Bokeh依次实现这些柱状图。

02 实例

柱状图代码示例如下所示。

  • 代码示例 2-27

1p = figure(plot_width=400, plot_height=400)
2p.vbar(x=[1, 2, 3], width=0.5, bottom=0,
3       top=[1.2, 2.5, 3.7], color="red")   # 垂直柱状图
4show(p)  # 显示

运行结果如图2-40所示。

▲图2-40 代码示例2-27运行结果

代码示例2-27第2行采用vbar()方法实现垂直柱状图,该方法具体的参数说明如下。

p.vbar(x, width, top, bottom=0, **kwargs)参数说明。

  • x (:class:`~bokeh.core.properties.NumberSpec` ) : 柱中心x轴坐标

  • width (:class:`~bokeh.core.properties.NumberSpec` ) : 柱宽

  • top (:class:`~bokeh.core.properties.NumberSpec` ) : 柱顶部y轴坐标

  • bottom (:class:`~bokeh.core.properties.NumberSpec` ) : 柱底部y轴坐标

  • 代码示例 2-28

1p = figure(plot_width=400, plot_height=400)
2p.hbar(y=[1, 2, 3], height=0.5, left=0,
3       right=[1.2, 2.5, 3.7], color="navy")  # 水平柱状图
4show(p)  # 显示

运行结果如图2-41所示。

▲图2-41 代码示例2-28运行结果

代码示例2-28第2行采用hbar()方法实现横向柱状图,该方法具体的参数说明如下。

p.hbar(y, height, right, left=0, **kwargs)参数说明。

  • y (:class:`~bokeh.core.properties.NumberSpec` ) : 柱中心y轴坐标

  • height (:class:`~bokeh.core.properties.NumberSpec` ) :柱的高度(宽度)

  • right (:class:`~bokeh.core.properties.NumberSpec` ) :柱右侧边界x轴坐标

  • left (:class:`~bokeh.core.properties.NumberSpec` ) :柱左侧边界x轴坐标

  • 代码示例 2-29

1from bokeh.models import ColumnDataSource
2from bokeh.palettes import Spectral6
3import pandas as pd
4df=pd.read_csv('data/visualization-20190505.csv')
5p = figure(x_range=df['Visualization_tools'],title="2019年5月常见可视化工具源码GitHub标星数量")
6p.vbar(x=df['Visualization_tools'], top=df['Star'] , width=0.8, color=Spectral6)
7p.xgrid.grid_line_color = None
8p.y_range.start = 0
9show(p)

运行结果如图2-42所示。

▲图2-42 代码示例2-29运行结果

代码示例2-29第6行采用vbar()方法展示集中可视化开源工具在GitHub上的Stars数,可以看出Bokeh已经超过了Matplotlib。

  • 代码示例 2-30

 1# 数据  2fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']3counts = [5, 3, 4, 2, 4, 6]  4# 画布  5p = figure(x_range=fruits, plot_height=350, title="Fruit Counts",  6#            toolbar_location=None,  7#            tools=""  8         )  9# 柱状图
10p.vbar(x=fruits, top=counts, width=0.9)
11# 坐标轴设置
12p.xgrid.grid_line_color = None
13p.y_range.start = 0
14# 显示
15show(p)

运行结果如图2-43所示。

▲图2-43 代码示例2-30运行结果

代码示例2-30第10行采用vbar()方法展示了几种水果的销量。

  • 代码示例 2-31

 1# 数据  2fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']3counts = [5, 3, 4, 2, 4, 6]  4# 排序  5sorted_fruits = sorted(fruits, key=lambda x: counts[fruits.index(x)])  6# 画布  7p = figure(x_range=sorted_fruits, plot_height=350, title="Fruit Counts",  8#            toolbar_location=None, tools=""  9          )
10# 绘图
11p.vbar(x=fruits, top=counts, width=0.9)
12# 其他
13p.xgrid.grid_line_color = None
14p.y_range.start = 0
15# 显示
16show(p)

运行结果如图2-44所示。

▲图2-44 代码示例2-31运行结果

代码示例2-31第5行先用sorted()方法对原始数据进行排序;然后在第11行采用vbar()方法展示了几种水果的销量。

  • 代码示例 2-32

 1from bokeh.models import ColumnDataSource  2from bokeh.palettes import Spectral6  3from bokeh.transform import factor_cmap  4# 数据  5fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']6counts = [5, 3, 4, 2, 4, 6]  7source = ColumnDataSource(data=dict(fruits=fruits, counts=counts))  8# 画布  9p = figure(x_range=fruits, plot_height=350, toolbar_location=None, title="Fruit Counts")
10# 绘图,分组颜色映射
11p.vbar(x='fruits', top='counts', width=0.9, source=source, legend="fruits",
12       line_color='white', fill_color=factor_cmap('fruits', palette=Spectral6, factors=fruits))
13# 坐标轴、图例设置
14p.xgrid.grid_line_color = None
15p.y_range.start = 0
16p.y_range.end = 9
17p.legend.orientation = "horizontal"
18p.legend.location = "top_center"
19show(p)

运行结果如图2-45所示。

▲图2-45 代码示例2-32运行结果

代码示例2-32第11行采用vbar()方法展示了几种水果的销量,其中line_color、fill_color分别为柱的轮廓线颜色和填充颜色,factor_cmap采用数据分类进行颜色映射。在代码实例2-27中,也可以通过color直接定义颜色列表。

  • 代码示例 2-33

 1from bokeh.models import ColumnDataSource  2from bokeh.palettes import Spectral6  # ['#3288bd', '#99d594', '#e6f598', '#fee08b', '#fc8d59', '#d53e4f']3fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']4counts = [5, 3, 4, 2, 4, 6]  5source = ColumnDataSource(data=dict(fruits=fruits, counts=counts, color=Spectral6))6p = figure(x_range=(0,9), y_range=fruits, plot_height=250, title="Fruit Counts",7#            toolbar_location=None, tools=""  8          )  9p.hbar(y='fruits',left=0,right='counts', height=0.5 ,color='color', legend="fruits", source=source)
10p.xgrid.grid_line_color = None
11# p.legend.orientation = "horizontal"
12p.legend.location = "top_right"
13show(p)

运行结果如图2-46所示。

代码示例2-33第9行采用hbar()方法展示了几种水果的销量,并使用color直接定义颜色列表。

▲图2-46 代码示例2-33运行结果

  • 代码示例 2-34

 1fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']2years = ['2015', '2016', '2017']  3data = {'fruits' : fruits,  4             '2015'   : [2, 1, 4, 3, 2, 4],  5             '2016'   : [5, 3, 3, 2, 4, 6],  6             '2017'   : [3, 2, 4, 4, 5, 3]}  7# 创建复合列表 [ ("Apples", "2015"), ("Apples", "2016"), ("Apples", "2017"), ("Pears", "2015), ... ]  8x = [ (fruit, year) for fruit in fruits for year in years ]  9counts = sum(zip(data['2015'], data['2016'], data['2017']), ()) # 分组求和(堆叠总数)
10source = ColumnDataSource(data=dict(x=x, counts=counts))
11# 画布
12p = figure(x_range=FactorRange(*x), plot_height=350, title="Fruit Counts by Year",
13#            toolbar_location=None, tools=""
14          )
15# 柱状图
16p.vbar(x='x', top='counts', width=0.9, source=source)
17# 其他
18p.y_range.start = 0
19p.x_range.range_padding = 0.1
20p.xaxis.major_label_orientation = 1
21p.xgrid.grid_line_color = None
22# 显示
23show(p)

运行结果如图2-47所示。

代码示例2-34第8、9行数据预处理,读者可以打印数据格式;笔者建议在实践中多采用Pandas进行数据预处理,其DataFrames的复合序列可以直接作为分组柱状图的数据。

▲图2-47 代码示例2-34运行结果

  • 代码示例 2-35

 1# 数据  2fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']3years = ['2015', '2016', '2017']  4data = {'fruits' : fruits,  5        '2015'   : [2, 1, 4, 3, 2, 4],  6        '2016'   : [5, 3, 3, 2, 4, 6],  7        '2017'   : [3, 2, 4, 4, 5, 3]}  8palette = ["#c9d9d3", "#718dbf", "#e84d60"]  9x = [ (fruit, year) for fruit in fruits for year in years ]
10counts = sum(zip(data['2015'], data['2016'], data['2017']), ()) # like an hstack
11source = ColumnDataSource(data=dict(x=x, counts=counts))
12# 画布
13p = figure(x_range=FactorRange(*x), plot_height=350, title="Fruit Counts by Year",
14#            toolbar_location=None, tools=""
15          )
16# 绘图
17p.vbar(x='x', top='counts', width=0.9, source=source, line_color="white",
18       fill_color=factor_cmap('x', palette=palette, factors=years, start=1, end=2))
19# 其他
20p.y_range.start = 0
21p.x_range.range_padding = 0.1
22p.xaxis.major_label_orientation = 1
23p.xgrid.grid_line_color = None
24# 显示
25show(p)

运行结果如图2-48所示。

▲图2-48 代码示例2-35运行结果

代码示例2-35在代码示例2-33的基础上增加了柱状图颜色(第18行),factor_cmap方法是将色板对应的颜色列表映射到相应的分类数据上。

  • 代码示例 2-36

 1from bokeh.core.properties import value  2from bokeh.transform import dodge    3# 数据  4fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']  5years = ['2015', '2016', '2017']  6data = {'fruits' : fruits,  7             '2015'   : [2, 1, 4, 3, 2, 4],  8             '2016'   : [5, 3, 3, 2, 4, 6],  9             '2017'   : [3, 2, 4, 4, 5, 3]}
10source = ColumnDataSource(data=data)
11# 画布
12p = figure(x_range=fruits, y_range=(0, 10), plot_height=350, title="Fruit Counts by Year",
13#            toolbar_location=None, tools=""
14          )
15# 绘图,采用doge数据转换,按产品种类不同年份分组显示
16p.vbar(x=dodge('fruits', -0.25, range=p.x_range), top='2015', width=0.2, source=source,
17       color="#c9d9d3", legend=value("2015"))
18
19p.vbar(x=dodge('fruits',  0.0,  range=p.x_range), top='2016', width=0.2, source=source,
20       color="#718dbf", legend=value("2016"))
21
22p.vbar(x=dodge('fruits',  0.25, range=p.x_range), top='2017', width=0.2, source=source,
23       color="#e84d60", legend=value("2017"))
24# 其他参数设置
25p.x_range.range_padding = 0.1
26p.xgrid.grid_line_color = None
27p.legend.location = "top_left"
28p.legend.orientation = "horizontal"
29# 显示
30show(p)

运行结果如图2-49所示。

▲图2-49 代码示例2-36运行结果

代码示例2-36第16、19、22使用vbar()方法分别绘制2015—2017年各种水果的销量;其中dodge方法按每年不同种类水果的数据分散绘制在x轴范围内,是将色板对应的颜色列表映射到相应的分类数据上,dodge第二个参数表示该分类的起始绘制点。

  • 代码示例 2-37

 1from bokeh.core.properties import value  2# 数据  3fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']  4years = ["2015", "2016", "2017"]  5colors = ["#c9d9d3", "#718dbf", "#e84d60"]  6data = {'fruits' : fruits,  7        '2015'   : [2, 1, 4, 3, 2, 4],  8        '2016'   : [5, 3, 4, 2, 4, 6],  9        '2017'   : [3, 2, 4, 4, 5, 3]}
10# 画布
11p = figure(x_range=fruits, plot_height=250, title="Fruit Counts by Year",
12#            toolbar_location=None,
13#            tools="hover",
14           tooltips="$name @fruits: @$name")
15# 绘图,直接堆叠各年数据
16p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=data,
17             legend=[value(x) for x in years]) # legend=[{'value': '2015'}, {'value': '2016'}, {'value': '2017'}]
18# 其他
19p.y_range.start = 0
20p.x_range.range_padding = 0.1
21p.xgrid.grid_line_color = None
22p.axis.minor_tick_line_color = None
23p.outline_line_color = None
24p.legend.location = "top_left"
25p.legend.orientation = "horizontal"
26# 显示
27show(p)

运行结果如图2-50所示。

▲图2-50 代码示例2-37运行结果

代码示例2-37第16行使用vbar_stack()方法实现竖向堆叠柱状图,该方法具体的参数说明如下。

p.vbar_stack(stackers, **kw)参数说明。

  • stackers (seq[str]) : 列表,由绘图数据中需要进行堆叠的数据列名称组成。

其他参数基本上同vbar()方法。

  • 代码示例 2-38

 1from bokeh.models import Legend  2p = figure(y_range=fruits, plot_height=250,title="Fruit Counts by Year",  3#            toolbar_location=None, tools=""  4          )  5source = ColumnDataSource(data=data)  6p.hbar_stack(years, y='fruits',height=0.8, color=colors, source=source,  7            legend=[value(x) for x in years] )  # 堆叠柱状图,逐年堆叠  8p.x_range.start = 0  9p.y_range.range_padding = 0.1 # x轴两侧空白
10p.ygrid.grid_line_color = None
11p.axis.minor_tick_line_color = None
12p.outline_line_color = None
13p.legend.location = "top_right"
14# p.legend.orientation = "horizontal"
15p.legend.click_policy="hide"
16show(p)

运行结果如图2-51所示。

▲图2-51 代码示例2-38运行结果

代码示例2-38第6行使用hbar_stack()方法实现横向堆叠柱状图,该方法具体的参数说明如下。

p.hbar_stack(stackers, **kw)参数说明。

  • stackers (seq[str]) : 列表,由绘图数据中需要进行堆叠的数据列名称组成。

其他参数基本上同vbar()方法。

在学习或时间过程中,图例可能遮盖图表,此时可以将图例移到坐标轴外或单独作为一个图层。

  • 代码示例 2-39

 1from bokeh.palettes import Spectral5  2from bokeh.sampledata.autompg import autompg as df  3from bokeh.transform import factor_cmap  4# 数据,预处理  5df.cyl = df.cyl.astype(str)  6group = df.groupby('cyl')  7cyl_cmap = factor_cmap('cyl', palette=Spectral5, factors=sorted(df.cyl.unique())) # 分组颜色映射  8# 画布  9p = figure(plot_height=350, x_range=group, title="MPG by # Cylinders",
10#            toolbar_location=None, tools=""
11          )
12# 绘图
13p.vbar(x='cyl', top='mpg_mean', width=0.9, source=group,
14       line_color=cyl_cmap, fill_color=cyl_cmap)
15# 其他
16p.y_range.start = 0
17p.xgrid.grid_line_color = None
18p.xaxis.axis_label = "some stuff"
19p.xaxis.major_label_orientation = 1.2
20p.outline_line_color = None
21# 显示
22show(p)

运行结果如图2-52所示。

▲图2-52 代码示例2-39运行结果

代码示例2-39第13行使用vbar()用柱状图展示了汽车缸数与每加仑汽油能行驶的英里数之间的关系。

  • 代码示例 2-40

 1from bokeh.sampledata.autompg import autompg_clean as df  2df.cyl = df.cyl.astype(str)  3df.yr = df.yr.astype(str)  4group = df.groupby(['cyl', 'mfr']) # 复合条件分组,[缸数、厂家]  5index_cmap = factor_cmap('cyl_mfr', palette=Spectral5, factors=sorted(df.cyl.unique()), end=1)  6# 画布  7p = figure(plot_width=800, plot_height=300, title="Mean MPG by # Cylinders and Manufacturer",  8           x_range=group, tooltips=[("MPG", "@mpg_mean"), ("Cyl, Mfr", "@cyl_mfr")])  9# 绘图
10p.vbar(x='cyl_mfr', top='mpg_mean', width=1, source=group,
11       line_color="white", fill_color=index_cmap, ) # 尾气排放量均值
12# 其他
13p.y_range.start = 0
14p.x_range.range_padding = 0.05  # 同css中的padding
15p.xgrid.grid_line_color = None
16p.xaxis.axis_label = "Manufacturer grouped by # Cylinders"
17p.xaxis.major_label_orientation = 1.2 # x轴标签旋转
18p.outline_line_color = None
19# 显示
20show(p)

运行结果如图2-53所示。

▲图2-53 代码示例2-40运行结果

代码示例2-40第10行使用vbar()绘制分组柱状图,数据分组采用Pandas的groupby方法,该数据为复合序列,展示了汽车缸数与每加仑汽油能行驶的英里数之间的关系。

  • 代码示例 2-41

 1# 数据  2from bokeh.sampledata.sprint import sprint  3sprint.Year = sprint.Year.astype(str)  4group = sprint.groupby('Year')  5source = ColumnDataSource(group)  6# 画布  7p = figure(y_range=group, x_range=(9.5,12.7), plot_width=400, plot_height=550,   8#            toolbar_location=None,  9           title="Time Spreads for Sprint Medalists (by Year)")
10# 绘图
11p.hbar(y="Year", left='Time_min', right='Time_max', height=0.4, source=source) # 水平柱状图
12# 其他
13p.ygrid.grid_line_color = None
14p.xaxis.axis_label = "Time (seconds)"
15p.outline_line_color = None
16# 显示
17show(p)

运行结果如图2-54所示。

▲图2-54 代码示例2-41运行结果

代码示例2-41第11行使用hbar()绘制瀑布图,参数中left、right为柱左、右坐标。若左侧的起始坐标均为某一定值,则变回横向柱状图。

  • 代码示例 2-42

 1from bokeh.core.properties import value  2from bokeh.models import ColumnDataSource, FactorRange  3# 数据  4factors = [  5        ("Q1", "jan"), ("Q1", "feb"), ("Q1", "mar"),  6        ("Q2", "apr"), ("Q2", "may"), ("Q2", "jun"),  7        ("Q3", "jul"), ("Q3", "aug"), ("Q3", "sep"),  8        ("Q4", "oct"), ("Q4", "nov"), ("Q4", "dec"),  9
10]
11regions = ['east', 'west']
12source = ColumnDataSource(data=dict(
13       x=factors,
14       east=[ 5, 5, 6, 5, 5, 4, 5, 6, 7, 8, 6, 9 ],
15       west=[ 5, 7, 9, 4, 5, 4, 7, 7, 7, 6, 6, 7 ],
16))
17# 画布
18p = figure(x_range=FactorRange(*factors), plot_height=250,
19#                    toolbar_location=None, tools=""
20          )
21# 绘图
22p.vbar_stack(regions, x='x', width=0.9, alpha=0.5, color=["blue", "red"], source=source,
23                   legend=[value(x) for x in regions])
24# 其他
25p.y_range.start = 0
26p.y_range.end = 18
27p.x_range.range_padding = 0.1
28p.xaxis.major_label_orientation = 1
29p.xgrid.grid_line_color = None
30p.legend.location = "top_center"
31p.legend.orientation = "horizontal"
32# 显示
33show(p)

运行结果如图2-55所示。

▲图2-55 代码示例2-42运行结果

代码示例2-42第18行使用FactorRange ()方法预定义x轴的范围(factors的数据格式与Pandas复合序列相似);第19行绘制竖向堆叠柱状图。与常规竖向堆叠柱状图相比,该图采用了复合序列,多展示了一个维度。

  • 代码示例 2-43

 1from bokeh.models import ColumnDataSource  2from bokeh.palettes import GnBu3, OrRd3  3# 数据  4fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']  5years = ["2015", "2016", "2017"]  6exports = {'fruits' : fruits,  7           '2015'   : [2, 1, 4, 3, 2, 4],  8           '2016'   : [5, 3, 4, 2, 4, 6],  9           '2017'   : [3, 2, 4, 4, 5, 3]}
10imports = {'fruits' : fruits,
11           '2015'   : [-1, 0, -1, -3, -2, -1],
12           '2016'   : [-2, -1, -3, -1, -2, -2],
13           '2017'   : [-1, -2, -1, 0, -2, -2]}
14# 画布
15p = figure(y_range=fruits, plot_height=350, x_range=(-16, 16), title="Fruit import/export, by year",
16#            toolbar_location=None
17          )
18# 水平堆积柱状图出口(正向)
19p.hbar_stack(years, y='fruits', height=0.9, color=GnBu3, source=ColumnDataSource(exports),
20             legend=["%s exports" % x for x in years])
21# 水平堆积柱状图进口(负向)
22p.hbar_stack(years, y='fruits', height=0.9, color=OrRd3, source=ColumnDataSource(imports),
23             legend=["%s imports" % x for x in years])
24# 其他
25p.y_range.range_padding = 0.1
26p.ygrid.grid_line_color = None
27p.legend.location = "top_left"
28p.axis.minor_tick_line_color = None
29p.outline_line_color = None
30# 显示
31show(p)

运行结果如图2-56所示。

代码示例2-43第19、22行分别使用hbar_stack ()方法向左、右两个方向绘制,实现横向堆叠柱状图;注意,当y轴为分类数据(字符串)时,一般需要预先定义y_range。笔者在实践中习惯用该图,不受纵向长度约束,适合数据较多的长图,例如全国各省某类型数据的比较。

▲图2-56 代码示例2-43运行结果

  • 代码示例 2-44

 1from bokeh.models import FactorRange  2factors = [  3       ("Q1", "jan"), ("Q1", "feb"), ("Q1", "mar"),  4       ("Q2", "apr"), ("Q2", "may"), ("Q2", "jun"),  5       ("Q3", "jul"), ("Q3", "aug"), ("Q3", "sep"),  6       ("Q4", "oct"), ("Q4", "nov"), ("Q4", "dec"),  78] # 复合数列  9p = figure(x_range=FactorRange(*factors), plot_height=350,
10#                    toolbar_location=None, tools=""
11          ) # 如果不采用ColumnDataSource,就必须预定义factors
12x = [ 10, 12, 16, 9, 10, 8, 12, 13, 14, 14, 12, 16 ]
13# 水平柱状图
14p.vbar(x=factors, top=x, width=0.9, alpha=0.5)
15# 折线
16p.line(x=["Q1", "Q2", "Q3", "Q4"], y=[12, 9, 13, 14], color="red", line_width=2)
17# 其他
18p.y_range.start = 0
19p.x_range.range_padding = 0.1
20p.xaxis.major_label_orientation = 1
21p.xgrid.grid_line_color = None
22# 显示
23show(p)

运行结果如图2-57所示。

▲图2-57 代码示例2-44运行结果

关于作者:屈希峰,资深Python工程师,Bokeh领域的实践者和布道者,对Bokeh有深入的研究。擅长Flask、MongoDB、Sklearn等技术,实践经验丰富。知乎多个专栏(Python中文社区、Python程序员、大数据分析挖掘)作者,专栏累计关注用户十余万人。

本文摘编自《Python数据可视化:基于Bokeh的可视化绘图》,经出版方授权发布。

延伸阅读《Python数据可视化》

点击上图了解及购买

转载请联系微信:DoctorData

推荐语:从图形绘制、数据动态展示、Web交互等维度全面讲解Bokeh功能和使用,不含复杂数据处理和算法,深入浅出,适合零基础入门,包含大量案例。

有话要说????

Q: 你在哪些案例中使用柱状图?

欢迎留言与大家分享

猜你想看????

  • 沿用70多年的经典数据可视化方法,如何用Python实现?

  • 新手学Python, 如何从"入门到入土"变为"从入门到快速上车"?

  • 机器学习入门必读:6种简单实用算法及学习曲线、思维导图

  • 2020大风口!什么是图神经网络?有什么用?终于有人讲明白了

据统计,99%的大咖都完成了这个神操作

????

原来你也在看

柱状图、堆叠柱状图、瀑布图有什么区别?怎样用Python绘制?相关推荐

  1. 柱状图、堆叠柱状图、瀑布图有什么区别?怎样用Python绘制?(附代码)

    来源:大数据DT(ID:hzdashuju) 作者:屈希峰,资深Python工程师,知乎多个专栏作者 本文约8000字,建议阅读20分钟 柱状图是当前应用最广泛的图表之一,你几乎每天都可以在电子产品上 ...

  2. pyecharts-动态可视化(2) 柱状图 时间轴/折线/堆叠/水印/瀑布图

    pyecharts中 柱状图的形式 应该基本就在这了!!代码可以直接运行~超级详细的注释,还有动图呢!! 在制作柱状图可能会遇到的组合,所需用到的代码均做了注释,用的V1版本.非常的小白,非常的友好! ...

  3. 44Echarts - 柱状图(阶梯瀑布图)

    效果图 源代码 <!DOCTYPE html> <html><head><meta charset="utf-8"><titl ...

  4. python三维图能画地图_使用Python绘制地图的三大秘密武器

    原标题:使用Python绘制地图的三大秘密武器 Python地图可视化库有大家熟知的pyecharts.plotly.folium,还有稍低调的bokeh.basemap.geopandas,也是地图 ...

  5. (DEAP)基于图卷积神经网络的脑电情绪识别(附代码)

    1. 数据集介绍以及特征部分见上篇文章: DEAP数据集介绍以及特征提取部分 深度学习基于DEAP的脑电情绪识别情感分类(附代码)_qq_3196288251的博客-CSDN博客 2. 图卷积神经网络 ...

  6. glide加载gif图不显示动画_用Python绘制会动的柱形竞赛图

    我们经常看到的Bar Chart Race(柱形竞赛图),可以看到数据的呈现非常的直观.今天就一起来学习下如何生成和上面一样的柱形竞赛图. 1.导入Python库 2.加载数据集 这里使用的是城市人口 ...

  7. 十图详解TensorFlow数据读取机制(附代码)

    在学习TensorFlow的过程中,有很多小伙伴反映读取数据这一块很难理解.确实这一块官方的教程比较简略,网上也找不到什么合适的学习材料.今天这篇文章就以图片的形式,用最简单的语言,为大家详细解释一下 ...

  8. 循序渐进,学会用pyecharts绘制瀑布图

    循序渐进,学会用pyecharts绘制瀑布图 瀑布图简介 瀑布图(Waterfall Plot)是由麦肯锡顾问公司所独创的图表类型,因为形似瀑布流水而称之为瀑布图. 瀑布图采用绝对值与相对值结合的方式 ...

  9. Tableau图表 • 瀑布图

    瀑布图是数据可视化分析中的常用图表类型之一,可以形象的表示出一系列具有累计性质的数值之间的增减变化情况. 图:瀑布图示例(来源于网上) 这里使用tableau自带的超市示例,创建瀑布图分析子类别产品的 ...

最新文章

  1. Extjs PROXY查询params无法传参,改用extraParams
  2. Django之session
  3. 简单灵活的 PHP页面跳转函数
  4. Caffe学习笔记(4)--------用师兄的源码都差点没跑通觉得自己智商真的捉急!...
  5. MFC添加背景图片方法
  6. MSTP协议介绍和堆叠技术介绍
  7. 【Luogu】P4462异或序列(莫队)
  8. 为什么说 GraphQL 可以取代 REST API?
  9. 计算机二级web题目(7.2)--基本操作题1
  10. [记录] --- safari浏览器对于yyyy-MM的坑
  11. java executequery_java execute、executeQuery和executeUpdate之间的区别
  12. python编程(ply库)
  13. 语言新思路:接口+测试
  14. 年前的面试经历(二)
  15. cad导出pdf_CAD手机看图软件中怎么将CAD图纸转为PDF/图片格式?
  16. 非晶金属模型建模:Ovito方法
  17. 如何将电脑下载的电子书导入手机kindle APP
  18. 基于uniapp的个人课程表
  19. 网站开发进阶(二十六)js刷新页面方法大全
  20. IOC原理基本使用(一)

热门文章

  1. MySQL笔记-解决Can't connect to local MySQL server through socket '/xx/xx/mysql.sock' (111)及(2)
  2. C++|Qt工作笔记-Windows平台下的句柄与Qt中QWindow::winId()以及 QPlatformWindow::handle的区别与联系
  3. C/C++ OpenCV五种滤波器综合示例
  4. HTML期末作业-旅游网页
  5. HTML期末大网页作业-腾讯官网
  6. django 用户认证
  7. linux读取dmp备份数据打开,Linux 中 Oracle dmp 文件导入导出(转)
  8. query.exec报QSqlQuery::exec: database not open
  9. Java实现的时钟置换算法_时钟页面置换算法
  10. linux搭建测试环境常见问题,在Linux环境下搭建CCID测试环境