第一章 Matplotlib 简介
这里涉及Matplotlib 数据可视化模块的多个方面。 Matplotlib 能够创建多数类型的图表,如条形图,散点图,条形图,饼图,堆叠图,3D 图和地图图表。
首先,为了实际使用 Matplotlib,我们需要安装它。
如果你安装了更高版本的 Python,你应该能够打开cmd.exe
或终端,然后执行:
pip install matplotlib
注意:如果上面的较短命令不工作,你可能需要执行C:/Python34/Scripts/pip install matplotlib
。
如果在导入matplotlib
时,你会收到类似『无命名模块』和模块名称的错误,这意味着你还需要安装该模块。 一个常见的问题是缺少名为six
的模块。 这意味着你需要使用pip
安装six
。
或者,你可以前往 Matplotlib.org 并通过访问下载页面下载适当的版本进行安装。 请记住,因为你的操作系统为 64 位,你不一定需要 64 位版本的 Python。 如果你不打算尝试 64 位,你可以使用 32 位。 打开 IDLE 并阅读顶部。 如果它说你是 64 位,你就是 64 位,如果它说是 32 位,那么你就是 32 位。 一旦你安装了 Python,你就做好了准备,你可以编写任何你想要的逻辑。 我喜欢使用 IDLE 来编程,但你可以随意使用任何你喜欢的东西。
import matplotlib.pyplot as plt
这一行导入集成的pyplot
,我们将在整个系列中使用它。 我们将pyplot
导入为plt
,这是使用pylot
的 python 程序的传统惯例。
plt.plot([1,2,3],[5,7,4])
接下来,我们调用plot
的.plot
方法绘制一些坐标。 这个.plot
需要许多参数,但前两个是'x'
和'y'
坐标,我们放入列表。 这意味着,根据这些列表我们拥有 3 个坐标:1,5
2,7
和3,4
。
plt.plot
在后台『绘制』这个绘图,但绘制了我们想要的一切之后,当我们准备好的时候,我们需要把它带到屏幕上。
plt.show()
这样,应该弹出一个图形。 如果没有,有时它可以弹出,或者你可能得到一个错误。 你的图表应如下所示:
image
这个窗口是一个 matplotlib 窗口,它允许我们查看我们的图形,以及与它进行交互和访问。 你可以将鼠标悬停在图表上,并查看通常在右下角的坐标。 你也可以使用按钮。 它们可能在不同的位置,但在上图中,这些按钮在左下角。
Home
(主页)
image
一旦你开始浏览你的图表,主页按钮会帮助你。 如果你想要返回原始视图,可以单击它。 在浏览图表之前单击此按钮将不会生效。
Forward/Back
(前进/后退)
image
这些按钮可以像浏览器中的前进和后退按钮一样使用。 你可以单击这些来移回到你之前的位置,或再次前进。
Pan
(平移)
image
你可以点击平移按钮,之后点击并拖拽你的图表。
Zoom
(缩放)
image
缩放按钮可让你单击它,然后单击并拖动出要放大的方形区域。 放大需要左键单击并拖动。 你也可以右键单击并拖动来缩小。
Configure Subplots
(配置子图)
image
此按钮允许你对图形和绘图配置各种间距选项。 点击它会弹出:
image
每个蓝色条形都是一个滑块,它允许你调整内边距。 其中有些现在没有任何效果,因为没有任何其他子图。 前四个值调整图形到窗口边缘的边距。 之后wspace
和hspace
对应于当你绘制多个子图时,它们的水平或竖直间距。
Save
(保存)
image
此按钮允许你以各种形式保存图形。
所以这是 matplotlib 的快速介绍,我们之后会涉及更多。
第二章 图例、标题和标签
在本教程中,我们将讨论 Matplotlib 中的图例,标题和标签。 很多时候,图形可以不言自明,但是图形带有标题,轴域上的标签和图例,来解释每一行是什么非常必要。
注:轴域(
Axes
)即两条坐标轴围城的区域。
从这里开始:
import matplotlib.pyplot as plt x = [1,2,3]y = [5,7,4]x2 = [1,2,3]y2 = [10,14,12]
这样我们可以画出两个线条,接下来:
plt.plot(x, y, label='First Line') plt.plot(x2, y2, label='Second Line')
在这里,我们绘制了我们已经看到的东西,但这次我们添加另一个参数label
。 这允许我们为线条指定名称,我们以后可以在图例中显示它。 我们的其余代码为:
plt.xlabel('Plot Number')plt.ylabel('Important var')plt.title('Interesting Graph\nCheck it out')plt.legend()plt.show()
使用plt.xlabel
和plt.ylabel
,我们可以为这些相应的轴创建标签。 接下来,我们可以使用plt.title
创建图的标题,然后我们可以使用plt.legend()
生成默认图例。 结果图如下:
image
第三章 条形图和直方图
这个教程中我们会涉及条形图和直方图。我们先来看条形图:
import matplotlib.pyplot as plt plt.bar([1,3,5,7,9],[5,2,7,8,2], label="Example one")plt.bar([2,4,6,8,10],[8,6,2,5,6], label="Example two", color='g')plt.legend()plt.xlabel('bar number')plt.ylabel('bar height')plt.title('Epic Graph\nAnother Line! Whoa')plt.show()
plt.bar
为我们创建条形图。 如果你没有明确选择一种颜色,那么虽然做了多个图,所有的条看起来会一样。 这让我们有机会使用一个新的 Matplotlib 自定义选项。 你可以在任何类型的绘图中使用颜色,例如g
为绿色,b
为蓝色,r
为红色,等等。 你还可以使用十六进制颜色代码,如#191970
。
image
接下来,我们会讲解直方图。 直方图非常像条形图,倾向于通过将区段组合在一起来显示分布。 这个例子可能是年龄的分组,或测试的分数。 我们并不是显示每一组的年龄,而是按照 20 ~ 25,25 ~ 30... 等等来显示年龄。 这里有一个例子:
import matplotlib.pyplot as plt population_ages = [22,55,62,45,21,22,34,42,42,4,99,102,110,120,121,122,130,111,115,112,80,75,65,54,44,43,42,48]bins = [0,10,20,30,40,50,60,70,80,90,100,110,120,130]plt.hist(population_ages, bins, histtype='bar', rwidth=0.8)plt.xlabel('x')plt.ylabel('y')plt.title('Interesting Graph\nCheck it out')plt.legend()plt.show()
产生的图表为:
image
对于plt.hist
,你首先需要放入所有的值,然后指定放入哪个桶或容器。 在我们的例子中,我们绘制了一堆年龄,并希望以 10 年的增量来显示它们。 我们将条形的宽度设为 0.8,但是如果你想让条形变宽,或者变窄,你可以选择其他的宽度。
第四章 散点图
接下来,我们将介绍散点图。散点图通常用于比较两个变量来寻找相关性或分组,如果你在 3 维绘制则是 3 个。
散点图的一些示例代码:
import matplotlib.pyplot as plt x = [1,2,3,4,5,6,7,8]y = [5,2,4,2,1,4,5,2]plt.scatter(x,y, label='skitscat', color='k', s=25, marker="o")plt.xlabel('x')plt.ylabel('y')plt.title('Interesting Graph\nCheck it out')plt.legend()plt.show()
结果为:
image
plt.scatter
不仅允许我们绘制x
和y
,而且还可以让我们决定所使用的标记颜色,大小和类型。 有一堆标记选项,请参阅 Matplotlib 标记文档中的所有选项。
第五章 堆叠图
在这篇 Matplotlib 数据可视化教程中,我们要介绍如何创建堆叠图。 堆叠图用于显示『部分对整体』随时间的关系。 堆叠图基本上类似于饼图,只是随时间而变化。
让我们考虑一个情况,我们一天有 24 小时,我们想看看我们如何花费时间。 我们将我们的活动分为:睡觉,吃饭,工作和玩耍。
我们假设我们要在 5 天的时间内跟踪它,因此我们的初始数据将如下所示:
import matplotlib.pyplot as plt days = [1,2,3,4,5]sleeping = [7,8,6,11,7]eating = [2,3,4,3,2]working = [7,8,7,2,2]playing = [8,5,7,8,13]
因此,我们的x
轴将包括day
变量,即 1, 2, 3, 4 和 5。然后,日期的各个成分保存在它们各自的活动中。 像这样绘制它们:
plt.stackplot(days, sleeping,eating,working,playing, colors=['m','c','r','k'])plt.xlabel('x')plt.ylabel('y')plt.title('Interesting Graph\nCheck it out')plt.show()
image
在这里,我们可以至少在颜色上看到,我们如何花费我们的时间。 问题是,如果不回头看代码,我们不知道什么颜色是什么。 下一个问题是,对于多边形来说,我们实际上不能为数据添加『标签』。 因此,在任何不止是线条,带有像这样的填充或堆叠图的地方,我们不能以固有方式标记出特定的部分。 这不应该阻止程序员。 我们可以解决这个问题:
import matplotlib.pyplot as plt days = [1,2,3,4,5]sleeping = [7,8,6,11,7]eating = [2,3,4,3,2]working = [7,8,7,2,2]playing = [8,5,7,8,13]plt.plot([],[],color='m', label='Sleeping', linewidth=5)plt.plot([],[],color='c', label='Eating', linewidth=5)plt.plot([],[],color='r', label='Working', linewidth=5)plt.plot([],[],color='k', label='Playing', linewidth=5)plt.stackplot(days, sleeping,eating,working,playing, colors=['m','c','r','k'])plt.xlabel('x')plt.ylabel('y')plt.title('Interesting Graph\nCheck it out')plt.legend()plt.show()
image
我们在这里做的是画一些空行,给予它们符合我们的堆叠图的相同颜色,和正确标签。 我们还使它们线宽为 5,使线条在图例中显得较宽。 现在,我们可以很容易地看到,我们如何花费我们的时间。
第六章 饼图
饼图很像堆叠图,只是它们位于某个时间点。 通常,饼图用于显示部分对于整体的情况,通常以%为单位。 幸运的是,Matplotlib 会处理切片大小以及一切事情,我们只需要提供数值。
import matplotlib.pyplot as plt slices = [7,2,2,13]activities = ['sleeping','eating','working','playing']cols = ['c','m','r','b']plt.pie(slices, labels=activities, colors=cols, startangle=90, shadow= True, explode=(0,0.1,0,0), autopct='%1.1f%%')plt.title('Interesting Graph\nCheck it out')plt.show()
image
在plt.pie
中,我们需要指定『切片』,这是每个部分的相对大小。 然后,我们指定相应切片的颜色列表。 接下来,我们可以选择指定图形的『起始角度』。 这使你可以在任何地方开始绘图。 在我们的例子中,我们为饼图选择了 90 度角,这意味着第一个部分是一个竖直线条。 接下来,我们可以选择给绘图添加一个字符大小的阴影,然后我们甚至可以使用explode
拉出一个切片。
我们总共有四个切片,所以对于explode
,如果我们不想拉出任何切片,我们传入0,0,0,0
。 如果我们想要拉出第一个切片,我们传入0.1,0,0,0
。
最后,我们使用autopct
,选择将百分比放置到图表上面。
第七章 从文件加载数据
很多时候,我们想要绘制文件中的数据。 有许多类型的文件,以及许多方法,你可以使用它们从文件中提取数据来图形化。 在这里,我们将展示几种方法。 首先,我们将使用内置的csv
模块加载CSV文件,然后我们将展示如何使用 NumPy(第三方模块)加载文件。
import matplotlib.pyplot as pltimport csv x = []y = []with open('example.txt','r') as csvfile: plots = csv.reader(csvfile, delimiter=',') for row in plots: x.append(int(row[0])) y.append(int(row[1]))plt.plot(x,y, label='Loaded from file!')plt.xlabel('x')plt.ylabel('y')plt.title('Interesting Graph\nCheck it out')plt.legend()plt.show()
image
这里,我们打开样例文件,包含以下数据:
1,5 2,3 3,4 4,7 5,4 6,3 7,5 8,7 9,4 10,4
接下来,我们使用csv
模块读取数据。 csv
读取器自动按行分割文件,然后使用我们选择的分隔符分割文件中的数据。 在我们的例子中,这是一个逗号。 注意:csv
模块和csv reader
不需要文件在字面上是一个.csv文件。 它可以是任何具有分隔数据的简单的文本文件。
一旦我们这样做了,我们将索引为 0 的元素存储到x
列表,将索引为 1 的元素存储到y
列表中。 之后,我们都设置好了,准备绘图,然后显示数据。
虽然使用 CSV 模块是完全正常的,但使用 NumPy 模块来加载我们的文件和数据,可能对我们更有意义。 如果你没有 NumPy,你需要按下面的步骤来获取它。 为了了解安装模块的更多信息,请参阅 pip 教程。 大多数人应该都能打开命令行,并执行pip install numpy
。
如果不能,请参阅链接中的教程。
一旦你安装了 NumPy,你可以编写如下代码:
import matplotlib.pyplot as pltimport numpy as np x, y = np.loadtxt('example.txt', delimiter=',', unpack=True)plt.plot(x,y, label='Loaded from file!')plt.xlabel('x')plt.ylabel('y')plt.title('Interesting Graph\nCheck it out')plt.legend()plt.show()
结果应该是相同的图表。 稍后,当我们加载数据时,我们可以利用 NumPy 为我们做一些更多的工作,但这是教程未来的内容。 就像csv
模块不需要一个特地的.csv
一样,loadtxt
函数不要求文件是一个.txt
文件,它可以是一个.csv
,它甚至可以是一个 python 列表对象。
第八章 从网络加载数据
除了从文件加载数据,另一个流行的数据源是互联网。 我们可以用各种各样的方式从互联网加载数据,但对我们来说,我们只是简单地读取网站的源代码,然后通过简单的拆分来分离数据。
import matplotlib.pyplot as pltimport numpy as npimport urllibimport matplotlib.dates as mdatesdef graph_data(stock): stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' source_code = urllib.request.urlopen(stock_price_url).read().decode() stock_data = [] split_source = source_code.split('\n') for line in split_source: split_line = line.split(',') if len(split_line) == 6: if 'values' not in line: stock_data.append(line)
这里有很多步骤。首先,我们看到import
。 pyplot
像往常一样导入,然后导入了numpy
,然后是用于访问互联网的urllib
,然后导入了matplotlib.dates
作为mdates
,它对于将日期戳转换为 matplotlib 可以理解的日期很有用。
接下来,我们开始构建我们的graph_data
函数。在这里,我们首先定义包含股票数据的网址。之后,我们写一些urllib
代码来访问该 URL,然后使用.read
读取源代码,之后我们继续解码该数据。如果你使用 Python 2,则不必使用decode
。
然后,我们定义一个空列表,这是我们将要放置股票数据的地方,我们也开始使用split_source
变量拆分数据,以换行符拆分。
现在,如果你去看源代码,用stock
替换 URL 中的+stock+
,像 AAPL 那样,你可以看到大多数页面数据确实是股票定价信息,但有一些头信息我们需要过滤掉。为此,我们使用一些基本的过滤,检查它们来确保每行有 6 个数据点,然后确保术语values
不在行中。
现在,我们已经解析了数据,并做好了准备。我们将使用 NumPy:
date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, delimiter=',', unpack=True, # %Y = full year. 2015 # %y = partial year 15 # %m = number month # %d = number day # %H = hours # %M = minutes # %S = seconds # 12-06-2014 # %m-%d-%Y converters={0: bytespdate2num('%Y%m%d')})
我们在这里所做的是,使用numpy
的loadtxt
函数,并将这六个元素解构到六个变量。 这里的第一个参数是stock_data
,这是我们加载的数据。 然后,我们指定delimiter
(这里是逗号),然后我们指定我们确实想要在这里解包变量,不是一个变量,而是我们定义的这组变量。 最后,我们使用可选的converters
参数来指定我们要转换的元素(0
),以及我们打算要怎么做。 我们传递一个名为bytespdate2num
的函数,它还不存在,但我们下面会编写它。
第九章 时间戳的转换
本教程的重点是将来自 Yahoo finance API 的日期转换为 Matplotlib 可理解的日期。 为了实现它,我们要写一个新的函数,bytespdate2num
。
def bytespdate2num(fmt, encoding='utf-8'): strconverter = mdates.strpdate2num(fmt) def bytesconverter(b): s = b.decode(encoding) return strconverter(s) return bytesconverter
此函数接受数据,基于编码来解码数据,然后返回它。
将此应用于我们的程序的其余部分:
import matplotlib.pyplot as pltimport numpy as npimport urllibimport matplotlib.dates as mdatesdef bytespdate2num(fmt, encoding='utf-8'): strconverter = mdates.strpdate2num(fmt) def bytesconverter(b): s = b.decode(encoding) return strconverter(s) return bytesconverterdef graph_data(stock): stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' source_code = urllib.request.urlopen(stock_price_url).read().decode() stock_data = [] split_source = source_code.split('\n') for line in split_source: split_line = line.split(',') if len(split_line) == 6: if 'values' not in line and 'labels' not in line: stock_data.append(line) date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, delimiter=',', unpack=True, # %Y = full year. 2015 # %y = partial year 15 # %m = number month # %d = number day # %H = hours # %M = minutes # %S = seconds # 12-06-2014 # %m-%d-%Y converters={0: bytespdate2num('%Y%m%d')}) plt.plot_date(date, closep,'-', label='Price') plt.xlabel('Date') plt.ylabel('Price') plt.title('Interesting Graph\nCheck it out') plt.legend() plt.show()graph_data('TSLA')
如果你绘制 TSLA,结果图应该看起来像这样:
image
第十章 基本的自定义
在 Matplotlib 教程中,我们将讨论一些可能的图表自定义。 为了开始修改子图,我们必须定义它们。 我们很快会谈论他们,但有两种定义并构造子图的主要方法。 现在,我们只使用其中一个,但我们会很快解释它们。
现在,修改我们的graph_data
函数:
def graph_data(stock): fig = plt.figure() ax1 = plt.subplot2grid((1,1), (0,0))
为了修改图表,我们需要引用它,所以我们将它存储到变量fig
。 然后我们将ax1
定义为图表上的子图。 我们在这里使用subplot2grid
,这是获取子图的两种主要方法之一。 我们将深入讨论这些东西,但现在,你应该看到我们有 2 个元组,它们提供了(1,1)
和(0,0)
。 1,1
表明这是一个 1×1 网格。 然后0,0
表明这个子图的『起点』将为0,0
。
接下来,通过我们已经编写的代码来获取和解析数据:
stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'source_code = urllib.request.urlopen(stock_price_url).read().decode()stock_data = []split_source = source_code.split('\n')for line in split_source: split_line = line.split(',') if len(split_line) == 6: if 'values' not in line and 'labels' not in line: stock_data.append(line)date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, delimiter=',', unpack=True, converters={0: bytespdate2num('%Y%m%d')})
下面,我们这样绘制数据:
ax1.plot_date(date, closep,'-', label='Price')
现在,由于我们正在绘制日期,我们可能会发现,如果我们放大,日期会在水平方向上移动。但是,我们可以自定义这些刻度标签,像这样:
for label in ax1.xaxis.get_ticklabels(): label.set_rotation(45)
这将使标签转动到对角线方向。 接下来,我们可以添加一个网格:
ax1.grid(True)
然后,其它东西我们保留默认,但我们也可能需要略微调整绘图,因为日期跑到了图表外面。 记不记得我们在第一篇教程中讨论的configure subplots
按钮? 我们不仅可以以这种方式配置图表,我们还可以在代码中配置它们,以下是我们设置这些参数的方式:
plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
现在,为了防止我们把你遗留在某个地方,这里是完整的代码:
import matplotlib.pyplot as pltimport numpy as npimport urllibimport matplotlib.dates as mdatesdef bytespdate2num(fmt, encoding='utf-8'): strconverter = mdates.strpdate2num(fmt) def bytesconverter(b): s = b.decode(encoding) return strconverter(s) return bytesconverterdef graph_data(stock): fig = plt.figure() ax1 = plt.subplot2grid((1,1), (0,0)) stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' source_code = urllib.request.urlopen(stock_price_url).read().decode() stock_data = [] split_source = source_code.split('\n') for line in split_source: split_line = line.split(',') if len(split_line) == 6: if 'values' not in line and 'labels' not in line: stock_data.append(line) date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, delimiter=',', unpack=True, converters={0: bytespdate2num('%Y%m%d')}) ax1.plot_date(date, closep,'-', label='Price') for label in ax1.xaxis.get_ticklabels(): label.set_rotation(45) ax1.grid(True)#, color='g', linestyle='-', linewidth=5) plt.xlabel('Date') plt.ylabel('Price') plt.title('Interesting Graph\nCheck it out') plt.legend() plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) plt.show()graph_data('TSLA')
结果为:
扫描下方二维码回复关键字数据处理获取资料
作者:JackHCC
链接:https://www.jianshu.com/p/b694a18b765a
来源:JackHCC