文章目录
第10章 可视化
俗话说得好,“一图胜千言”,可见图像给我们带来的震撼效果。生活如此,机器学习也如此,图的直观、简单明了同样给我不一样的感觉和理解。那么,如何把数据变成图?如何把一些比较隐含的规则通过图像展示出来呢?
本章主要介绍几个基于Python、TensorFlow开发的可视化的强大工具,具体包括:
matplotlib
pyecharts
10.1 matplotlib
matplotlib 是 Python 中最著名的2D绘图库,它提供了与 matlab 相似的 API,十分适合交互式绘图,简单明了,功能强大,而且可以方便地作为绘图控件,嵌入 GUI 应用程序中。下面我们进入matplotlib的世界,开始我们的数据可视化之旅。
10.1.1 matplotlib的基本概念
在介绍matplotlib前,首先要保证环境中安装了Python。建议使用Anaconda安装,因为Anaconda安装包中包含很多常用的工具包,如matplotlib、NumPy、Pandas、Sklearn等,并且后续的更新维护也非常方便。
在绘制我们的第一个图形之前,我们先来了解几个matplotlib的非常重要的概念,以帮助我们更快地理解matplotlib的各种API,以及能让你和你的同事使用一种大家都能听得懂的语言以及术语进行沟通。
matplotlib设置坐标主要参数配置详细说明及示例说明如下。
1)导入绘图相关模块;
2)生成数据;
3)plot绘制图形,(选 - 线条设置)设置线linestyle或标记marker;
4)(选 - 坐标轴设置 - 添加坐标标签)给x轴添加标签xlabel和y轴添加标签ylabel;
5)(选 - 坐标轴设置 - 添加坐标刻度)设置x轴的刻度xlim()和y轴的刻度ylim();
6)(选 - 图例设置label)设置图例legend();
7)输出图形show()。
下面来看一个使用matplotlib绘图的实例,具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# 导入绘图相关模块 import matplotlib.pyplot as plt import numpy as np %matplotlib inline #这句在jupyter notebook有用,如果在命令行执行时,无需这句! # 生成数据 x = np.arange(0, 20, 1) y1 = (x-3)**2 + 1 y2 = (x+5)**2 + 8 # 设置线的颜色、线宽、样式 plt.plot(x, y1, linestyle='-', color='b', linewidth=5.0, label='convert A') # 添加点,设置点的样式、颜色、大小 plt.plot(x, y2, marker='o', color='r', markersize=10, label='convert B') # 给x轴加上标签 plt.xlabel('x', size=15) # 给y轴加上标签 plt.ylabel('y', size=15, rotation=90, horizontalalignment='right', verticalalignment='center') # 设置x轴的刻度 plt.xlim(0, 20) # 设置y轴的刻度 plt.ylim(0, 400) # 设置图例 plt.legend(labels=['A', 'B'], loc='upper left', fontsize=15) # 输出图形 plt.show() |
使用matplotlib对数据进行可视化的示例的运行结果如图10-1所示。
图10-1 使用matplotlib对数据进行可视化
也可以把图10-1拆成两个图,代码如下。
1 2 3 4 5 6 7 |
# 设置线的颜色、线宽、样式plt.subplot(1, 2, 1) # 画板包含1行2列子图,当前画在第一行第一列图上 plt.plot(x, y1, linestyle='-', color='b', linewidth=5.0, label='convert A') plt.subplot(1, 2, 2) # 画板包含1行2列子图,当前画在第一行第二列图上 # 添加点,设置点的样式、颜色、大小 plt.plot(x, y2, marker='o', color='r', markersize=10, label='convert B') plt.show() |
把图10-1拆成两个图的运行结果如图10-2所示。
图10-2 把图5-1拆成两个图
10.1.2 使用matplotlib绘制图表
matplotlib能绘制出各种各样的图表,所以开发人员可根据需要展示的数据格式、内容以及要用图表来达到的效果来选择合适的图形种类。下面我们通过日常工作中最常用的4种图表来做一个演示。
1.柱状图
柱状图是指用一系列高度不等的纵向条纹或者线段直观地显示统计报告来帮助人们理解数据的分布情况。在绘制柱状图时,我们可以使用plt.bar(x,y,tick_label),给出x,y坐标值,同时给出x坐标轴上对应刻度的含义等,示例如下。
1 2 3 4 5 6 |
import matplotlib.pyplot as plt ages = [5, 20, 15, 25, 10] labels = ['Tom', 'Dick', 'Harry', 'Slim', 'Jim'] plt.bar(range(len(ages)), ages, tick_label=labels) plt.show() |
绘制出的柱状图如图10-3所示。
图10-3 柱状图
2. 折线图
折线图通常用来显示随时间变化而变化的连续的数据,它非常适用于展示在相等的时间间隔下的数据的变化趋势。比如,使用折线图展示一个系统从2010年到2020年的每年的注册人数。在绘制折线图时,我们可以使用plt.plot()。 下面我们用折线图来显示系统注册人数的变化情况。
1 2 3 4 5 6 7 8 9 |
import matplotlib.pyplot as plt import numpy as np years = range(2010, 2020) num_of_reg = np.random.randint(1000, 2000, 10) plt.plot(years, num_of_reg) plt.xticks(years) plt.show() |
绘制出的折线图如图10-4所示。
图10-4 折线图
从图10-4中我们可以直观地看到,系统的注册人数在2011年进入了一个谷值,而2014是峰值。
3. 饼图
饼图常常用来显示一个数据系列中各项的大小及其在整体中的占比。比如我们可以用下面的饼图来展示每个人的月收入,并显示他们的月收入占总体收入的比例。
1 2 3 4 5 6 |
import matplotlib.pyplot as plt import numpy as np incomings = [18882, 8543, 20012, 6311, 10000] # 各人的月收入 plt.pie(incomings, labels=labels, autopct='%1.1f%%') plt.show() |
绘制出的饼图如图10-5所示。
图10-5 饼图
4. 散点图
散点图是指在回归分析中数据点在坐标系平面上的分布图,用于表示因变量随自变量变化而变化的大致趋势,从而帮助我们根据其中的关系选择合适的函数对数据点进行拟合。下面我们绘制一张身高和体重关系的散点图。
1 2 3 4 5 6 7 8 |
import matplotlib.pyplot as plt heights = [110, 120, 130, 140, 150, 160, 165, 167, 169, 172, 173, 173, 175] weights = [60, 62, 65, 67, 68, 69, 69, 72, 71, 73, 73, 71, 71] #c指明标记颜色,s说明标记大小,marker指明标记形状 plt.scatter(heights, weights, c='b',s=100, marker='o') plt.show() |
绘制出的散点图如图10-6所示。
图10-6 散点图
除了上述介绍的4种图形,matplotlib还可以绘制其他图形,比如线箱图、极限图、气泡图等。感兴趣的读者可以自行查阅matplotlib的网站或者源代码,以了解更多内容。
10.1.3 使用rcParams
rcParams用于存放matplotlib的图表全局变量,我们可以用它来设置全局的图表属性,当然在进行具体图表绘制的时候,我们也可以对全局变量进行覆盖。下面介绍几个常用的全局变量。注意,如果想在图表中显示中文内容,比如显示中文标题,则需要在matplotlib的全局变量rcParams里进行设置。
1)没设置rcParams属性。
1 2 3 4 5 6 7 8 9 10 11 |
import matplotlib.pyplot as plt x=np.arange(-10,11) y=x**2 plt.plot(x,y) plt.title("抛物线") plt.xlabel("x坐标轴") plt.ylabel("y坐标轴") plt.show() plt.show() |
运行结果如图10-7所示。
图10-7 没有设置rcParams属性的情况
如图10-7所示,中文标题没有正确显示,而是随机变成几个方框。此时,通过rcParams设置文字属性即可使标题正确显示。
1 2 3 4 5 6 7 8 9 10 |
plt.rcParams['font.sans-serif']=['SimHei'] # 以下适用用mac系统 # plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] plt.rcParams['axes.unicode_minus'] = False plt.plot(x,y,color="blue",label="y=x**2") plt.title("抛物线") plt.xlabel("x坐标轴") plt.ylabel("y坐标轴") plt.show() |
运行结果如图10-8所示。
图10-8 设置rcParams属性的情况
更多关于rcParams的设置问题,请参照matplotlib官网(https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.RcParams)。
10.2 pyecharts
我们接下来要介绍的pyecharts正是Python版本的eCharts。
相较于经典的matplotlib,pyecharts可以在保证易用、简洁、交互性的基础上让开发人员绘制出种类更加丰富(比如3D,和地图模块的集成)、样式更加新颖的图表。下面我们先来看如何安装pyecharts 。
10.2.1 pyecharts安装
pyecharts 是一个用于生成 ECharts 图表的类库,官网为https://pyecharts.org/。
pyecharts有两个大的版本,v0.5.x 以及 v1.x。其中, v0.5.x 支持 Python 2.7 以及Python 3.4, v1.x 支持Python 3.6及以上版本。考虑到v0.5版本已经不再维护,而且大多数公司已经升级到Python 3.7及以上版本,所以本节只介绍1.x版本,并且以最新版v1.9为基础进行讲解。pyecharts安装主要有两种方式,通过源码或者pip安装,这里以pip安装为例进行讲解:
1 |
pip install pyecharts |
【说明】安装pyecharts时,可改用国内的安装源,如清华安装源,以提高下载速度,具体代码如下:
1 |
pip install pyecharts -i https://pypi.tuna.tsinghua.edu.cn/simple some-package |
10.2.2 使用pyecharts绘制图表
我们先来用一个简单的例子直观地了解如何使用pyecharts绘图,体会它的便利性和优雅。
1 2 3 4 5 6 7 8 9 10 11 12 |
from pyecharts.charts import Bar from pyecharts import options bar = ( Bar() .add_xaxis(["鱼钩", "防晒用品", "鱼饵", "鱼线", "钓箱", "鱼竿"]) .add_yaxis("2020", [5, 20, 36, 10, 75, 90]) .add_yaxis("2021", [15, 6, 45, 20, 35, 66]) .set_global_opts(title_opts=options.TitleOpts(title="苏州某渔具公司", subtitle='销售金额(万元)')) ) bar.render_notebook() # 运行在jupyter notebook 环境下 |
绘制出的pyecharts的柱状图如图10-9所示。
图10-9 pyecharts的柱状图
上述代码显示了苏州XX渔具店在2020年和2021年各种子品类的销售金额。 首先我们创建了一个Bar类型的图表,添加了X轴(add_xaxis)来代表各种品类,之后添加了两个Y轴的数据(add_yaxis)来代表2020年以及2021年的业绩。为了让图表更加容易理解,我们增加了标题以及副标题(title以及subtitle)。
用Pyecharts画的柱状图非常优雅,当然,用它画其他图形同样如此。绘制出的图形如下:
1. 仪表盘(Gauge)
我们第一个例子来模拟汽车的仪表盘,仪表盘上显示这辆汽车的最高时速,以及当前行驶速度,汽车仪表盘还会使用醒目的红色提醒驾驶员不要超速行驶,我们把这些信息一并添加到我们需要绘制的图形里面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from pyecharts import options as opts from pyecharts.charts import Gauge dashboard = ( Gauge() .add( series_name = "当前车速", data_pair= [("", 88)], min_=0, max_=240, split_number=12, # 当前时速为88, 最低0km/h 最高 240km/h, 分为12段 detail_label_opts=opts.LabelOpts(formatter="{value}km/h"), # 显示格式 axisline_opts=opts.AxisLineOpts( linestyle_opts=opts.LineStyleOpts( color=[(0.83, "#37a2da"), (1, "red")], width=20 # 超过240km/h的0.83后,仪表板变成红色,以警示 ) ), ) .set_global_opts( title_opts=opts.TitleOpts(title="汽车仪表盘"), legend_opts=opts.LegendOpts(is_show=False), ) ) #使图像在notebook显示 dashboard.render_notebook() |
运行结果:
图10-10 仪表盘
大家可以从上图看到,仪表盘图形(Gauge)非常适合展示进度或者占比信息,通常我们会把几个仪表盘图形组合成一个组合图表进行展示,这样能让使用者对全局的信息有个快速的了解。不如,我们可以用几个仪表盘图形展示我们集群里面各个节点的健康状态,它们的CPU的使用率,IO的吞吐是不是在一个可承受的范围内等等。
2、地理坐标系(Geo)
这几年,各大app推出一个显示用户出行轨迹的应用广受各位旅游达人以及飞人的喜欢,在一张中国地图或者世界地图上,用箭头代表自己的飞行路径,线段的粗细代表了飞行这条航线的频率,让用户对自己过去一年的行踪有个直观的认识,也当做是在朋友圈凡尔赛的资料。接下来,我们用pyecharts来大概模拟这个功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
from pyecharts import options as opts from pyecharts.charts import Geo from pyecharts.globals import ChartType, SymbolType c = ( Geo() .add_schema(maptype="china") .add( "", [("上海", 1)], type_=ChartType.EFFECT_SCATTER, color="green", ) .add( "", [("北京", 11), ("大连", 3), ("西安", 4), ("重庆", 2), ("西藏", 4)], type_=ChartType.EFFECT_SCATTER, color="red", ) # 以下我们用两个城市绘制带有箭头的连线 .add( "", [("上海", "北京")], type_=ChartType.LINES, effect_opts=opts.EffectOpts( symbol=SymbolType.ARROW, symbol_size=11, color="blue" # 用symbol_size指定连线的宽度,以代表飞行的频率 ), linestyle_opts=opts.LineStyleOpts(curve=0.2), ) .add( "", [("上海", "大连")], type_=ChartType.LINES, effect_opts=opts.EffectOpts( symbol=SymbolType.ARROW, symbol_size=3, color="blue" ), linestyle_opts=opts.LineStyleOpts(curve=0.2), ) .add( "", [("上海", "西安")], type_=ChartType.LINES, effect_opts=opts.EffectOpts( symbol=SymbolType.ARROW, symbol_size=4, color="blue" ), linestyle_opts=opts.LineStyleOpts(curve=0.2), ) .add( "", [("上海", "重庆")], type_=ChartType.LINES, effect_opts=opts.EffectOpts( symbol=SymbolType.ARROW, symbol_size=2, color="blue" ), linestyle_opts=opts.LineStyleOpts(curve=0.2), ) .add( "", [("上海", "西藏")], type_=ChartType.LINES, effect_opts=opts.EffectOpts( symbol=SymbolType.ARROW, symbol_size=4, color="blue" ), linestyle_opts=opts.LineStyleOpts(curve=0.2), ) .set_series_opts(label_opts=opts.LabelOpts(is_show=False)) ) c.render_notebook() |
pyecharts内嵌了中国以及各个省份的矢量图,可以方便的绘制出你想要的区域,使用者可以通过使用坐标或者城市名称的形式标定出具体的位置,进而用不同的颜色代表特殊的含义。
10.2.3 从上海出发的航线图
用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线、路线的可视化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
from pyecharts import GeoLines, Style style = Style( title_top="#fff", title_pos = "center", width=1200, height=600, background_color="#31CAF6" ) data_shanghai = [ ["上海", "广州"], ["上海", "北京"], ["上海", "南京"], ["上海", "重庆"], ["上海", "兰州"], ["上海", "南昌"], ["上海", "武汉"], ["上海", "福建"], ["上海", "杭州"] ] style_geo = style.add( is_label_show=True, line_curve=0.2, line_opacity=0.6, legend_text_color="#eee", legend_pos="right", geo_effect_symbol="plane", geo_effect_symbolsize=15, label_color=['#a6c84c', '#ffa022', '#46bee9'], label_pos="right", label_formatter="{b}", label_text_color="#eee", ) geolines = GeoLines("GeoLines 示例", **style.init_style) geolines.add("从上海出发", data_shanghai, **style_geo) geolines.render("shanghai-out.html") |
打开shanghai-out.html
图10-11 从上海到各城市的航线图
10.3 实例:词云图
词云图又叫文字云,是对文本数据中出现频率较高的关键词予以视觉上的突出,形成"关键词的渲染"就类似云一样的彩色图片,从而过滤掉大量次要信息,使人一眼就可以领略文章的核心要义。
10.3.1 实例概况
实例环境:windows或linux,Python3.6+,jieba (中文分词),PIL(图像处理),wordcloud (词云表现)、matplotlib(图像显示)等。其中jieba、wordcloud需要用pip安装。具体安装方法如下:
1 2 |
pip install jieba pip install wordcloud |
文本信息:使用环球时报上一篇文章,题为《“中国芯”亟待顶层设计》
10.3.2 代码实现
【说明】大家可以从网络上随便采取一段文章作为输入文本(本例的输入文本为:chinese-core.txt),背景图片可以从网上随便下载一个作为词云背景图(本例的背景图像:back.jpg)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import numpy as np from PIL import Image import matplotlib.pyplot as plt #绘图库 import jieba #分词库 from wordcloud import WordCloud,STOPWORDS,ImageColorGenerator #词云库 #1、读入txt文本数据 text = open(r'.\data\chinese-core.txt',"rb").read() #2、结巴分词,默认精确模式。可以添加自定义词典userdict.txt,然后jieba.load_userdict(file_name) ,file_name为文件类对象或自定义词典的路径 # 自定义词典格式和默认词库dict.txt一样,一个词占一行:每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒 cut_text= jieba.cut(text) result= "/".join(cut_text)#必须给个符号分隔开分词结果来形成字符串,否则不能绘制词云 #print(result) #3、初始化自定义背景图片 image = Image.open(r'.\data\back.jpg') graph = np.array(image) #3、生成词云图,这里需要注意的是WordCloud默认不支持中文,所以这里需已下载好的中文字库 #5、绘制文字的颜色以背景图颜色为参考 image_color = ImageColorGenerator(graph)#从背景图片生成颜色值 #无自定义背景图:需要指定生成词云图的像素大小,默认背景颜色为黑色,统一文字颜色:mode='RGBA'和colormap='pink' wc = WordCloud(font_path=r".\data\ttf\msyh.ttc",max_font_size=50,background_color='white', max_words=1000,color_func=image_color,mode='RGBA',colormap='pink')#background_color='white' wc.generate(result) #wc.recolor(color_func=image_color) wc.to_file(r".\data\wordcloud.png") #按照设置的像素宽高度保存绘制好的词云图,比下面程序显示更清晰 # 4、显示图片 plt.figure("词云图") #指定所绘图名称 plt.imshow(wc) # 以图片的形式显示词云 plt.axis("off") #关闭图像坐标系 plt.show() |
图10-12 词云图
10.4 练习
1、尝试用其他主题文章进行词云展示。
2、尝试使用pyecharts的WordCloud画一下词云图,然后比较一下与有何区别。