学习使用在upyter笔记本中的Matplotlib

179 阅读11分钟

Matplotlib是一个Python库,经常与Jupyter Notebook一起使用。matplotlib中使用的模块被称为pyplot。在本教程中,我们将学习一点关于matplotlib的知识以及如何在Jupyter Notebook中使用它。Matplotlib.pyplot提供了一种类似MATLAB的绘图方式。这意味着pyplot有很多函数可以对一个图进行修改。Matplotlib与Jupyter Notebook的结合是一种流行的方式,使用Python将数据可视化,用于科学、技术和教育领域的各种应用。


安装Matplotlib

确保你首先[安装了Jupyter笔记本],然后我们可以将Matplotlib添加到我们的虚拟环境中。要做到这一点,导航到命令提示符,然后输入pip install matplotlib

pip install matplotlib

现在,只需在命令提示符下输入jupyter notebook即可启动你的Jupyter笔记本。

plt.plot(x,y)

线形图有点像matplotlib的 "你好世界"。下面的代码显示了如何使用x轴和y轴开始一个非常简单的线图。

import matplotlib.pyplot as plt

plt.plot([1, 2, 3], [2, 4, 3])

plt.show()

matplotlib pyplot plt

上面的代码首先使用import matplotlib.pyplot作为plt导入matplotlib。 这是导入和别名为plt的常见惯例。 现在我们可以利用.plot()函数。这个函数有许多可能的参数,但要知道的关键是,你必须向它传递一个x和一个y值。这些是数据的序列。在这个例子中,我们只是传递两个Python列表。第一个列表是x,第二个列表是y。这些序列应该总是等长的。在这一点上,我们已经准备好显示绘图,这可以用[plt.show()]来完成。


图例、标题和标签

现在我们可以谈谈matplotlib的另外三个重要方面。它们是图例、标题和标签。为你的图形设置一个标题,为x轴和y轴设置标签,以及一个解释数据的图例,这是一个好主意。首先,下面的代码为图表添加了X和Y的标签,以及标题。

import matplotlib.pyplot as plt

x = [1, 2, 3]
y = [2, 4, 3]

plt.plot(x, y)
plt.xlabel('X Label (Plot Number)')
plt.ylabel('Y Label (The Data)')

plt.title('My Cool Graph')
plt.show()

matplotlib label and title example

当有不止一个数据序列被绘制时,图例是很有用的。如果你在图上有不止一条线,你怎么知道哪条线代表什么?这就是你使用图例的原因。在添加图例时,同样重要的是要注意,你需要向plot()函数添加第三个参数。这是一个关键字参数,即 **label**的关键字,这样图例才能正确显示。下面是一个例子。

import matplotlib.pyplot as plt

x = [1, 2, 3]
y = [2, 4, 3]

x2 = [1, 2, 3]
y2 = [7, 7, 14]

plt.plot(x, y, label='First Line')
plt.plot(x2, y2, label='Second Line')
plt.xlabel('X Label (Plot Number)')
plt.ylabel('Y Label (The Data)')

plt.title('My Cool Graph')
plt.legend()
plt.show()

matplotlib legend example

柱状图和直方图

使用matplotlib显示条形图是通过.bar()函数完成的。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 3, 1, 7]

plt.bar(x, y, label='First Bars')

plt.xlabel('X Label (Plot Number)')
plt.ylabel('Y Label (The Data)')

plt.title('My Cool Graph')
plt.legend()
plt.show()

matplotlib barchart example

我们可以使用条形图绘制多组数据,就像我们使用线状图那样。在下面的代码中,我们使用x2和y2的变量添加了第二组数据。还注意到,我们现在对第一个x变量使用了奇数,对x2变量使用了偶数。我们需要这样做,以便条形图不会相互重叠。我们希望它们并排在一起,以便于比较,这一步就完成了。

import matplotlib.pyplot as plt

x = [1, 3, 5, 7, 9]
y = [2, 4, 3, 1, 7]

x2 = [2, 4, 6, 8, 10]
y2 = [2, 4, 4, 2, 6]

plt.bar(x, y, label='First Bars')
plt.bar(x2, y2, label='Second Bars')

plt.xlabel('X Label (Plot Number)')
plt.ylabel('Y Label (The Data)')

plt.title('My Cool Graph')
plt.legend()
plt.show()

matplotlib multi bar chart

另外,请注意,你可以在.bar()函数中指定条形图的颜色,就像这样。

plt.bar(x, y, label='First Bars', color='red')
plt.bar(x2, y2, label='Second Bars', color='black')

set bar color matplotlib

柱状图

直方图可以用来显示数据的分布。为了显示直方图,我们可以使用matplotlib.hist()函数。直方图有一个bin的概念。一个bin就像图形上的一个槽,用来存放数据的一个范围。在我们的例子中,bin是50000、60000、70000、80000、90000和100000。现在我们有一个工资列表。假设做了一个调查,检查信息技术领域有哪些常见的工资。任何在50000和59999之间的工资都应该归入50000仓。任何在60000和69999之间的工资都应该放在60000里,以此类推。

import matplotlib.pyplot as plt

salaries = [55312, 88143, 57423, 65872, 68154, 77554, 72345, 79492, 52310, 88541, 97000, 105234, 73198]
bins = [50000, 60000, 70000, 80000, 90000, 100000]

plt.hist(salaries, bins, histtype='bar', rwidth=0.7)

plt.xlabel('Salaries')
plt.ylabel('Number of people')

plt.title('My Cool Histogram')

plt.show()

matplotlib histogram bins

散点图

散点图可以用来在横轴和纵轴上绘制数据点,以显示一个变量受另一个变量的影响程度。数据表中的每一行都用一个点来表示,其位置取决于其在X轴和Y轴上设置的列的值。在matplotlib中,.scatter()函数被用来呈现散点图。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [9, 7, 3, 5, 2, 2, 1, 1, 6, 10]

plt.scatter(x, y)

plt.xlabel('This is X')
plt.ylabel('This is Y')

plt.title('My Cool Scatter Plot')

plt.show()

matplotlib scatter plot

绘图点的样式可以自定义。默认情况下,它只是一个简单的点,正如我们看到的那样。此外,标记的大小也可以调整。例如,你可能想让绘图点变大。下面是一个使用钻石形状和较大尺寸的散点图的例子。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [9, 7, 3, 5, 2, 2, 1, 1, 6, 10]

plt.scatter(x, y, marker='D', s=100)

plt.xlabel('This is X')
plt.ylabel('This is Y')

plt.title('My Cool Scatter Plot')

plt.show()

jupyter notebook scatter plot

堆积图

堆积图用于在同一组坐标轴上显示两组或更多的数据,或者你想将一个数据集按其组成部分进行分解。通常使用不同的颜色来区分各个组成部分。在我们下面的例子中,我们使用的是五天内的堆积图。有些人把堆积图称为时间的饼图。因此,我们有5天时间,每天我们给各种任务留出一定的时间。我们把这些分成电子邮件、代码审查、错误报告和互联网时间。因此,每个列表中的每个值都代表了这一天在该任务上花费的时间。一旦我们有了这些天数,我们就可以使用[.stackplot()]函数将其呈现在页面上。

import matplotlib.pyplot as plt

days = [1, 2, 3, 4, 5]

emails = [1, 1, 2, 3, 1]
codereviews = [2, 1, 1, 2, 3]
bugreports = [0, 0, 1, 0, 2]
internet = [3, 4, 2, 2, 5]

plt.stackplot(days, emails, codereviews, bugreports, internet,
              labels=['emails', 'codereviews', 'bugreports', 'internet'])

plt.xlabel('This is X')
plt.ylabel('This is Y')

plt.title('My Cool Stackplot')
plt.legend()
plt.show()

matplotlib stackplot example

饼图

在所有的图表类型中,饼图可能是最[基本]和最常见的。饼图看起来有点像一个真正的饼,因此得名。饼的每一片都是一个数据点。饼图经常被用来显示基于百分比的数据。当需要检查的数据点数量相对有限时,饼状图就非常好。如果你有太多的数据点,饼图就会被切成很多片,以至于可视化没有真正的好处。下面是一个以饼图形式重做的堆积图例子。请注意,当我们使用[.pie()]函数时,我们传入的是每项活动的所有时间的总和。

import matplotlib.pyplot as plt

days = [1, 2, 3, 4, 5]

emails = [1, 1, 2, 3, 1]
codereviews = [2, 1, 1, 2, 3]
bugreports = [0, 0, 1, 0, 2]
internet = [3, 4, 2, 2, 5]

slices = [sum(emails), sum(codereviews), sum(bugreports), sum(internet)]
tasks = ['emails', 'codereviews', 'bugreports', 'internet']

plt.pie(slices, labels=tasks)

plt.title('My Cool Pie Chart')
plt.legend()
plt.show()

matplotlib pie chart

相当酷啊!通过观察饼状图,我们可以看到我们的时间在一周内是如何被分配的。看起来我们在互联网上花了太多的时间了。

调整起始角度和百分比

当你渲染饼图时,matplotlib简单地选择了如何在页面上确定图表的方向。这可以通过设置 **startangle**和 **autopct**参数来指定。

import matplotlib.pyplot as plt

days = [1, 2, 3, 4, 5]

emails = [1, 1, 2, 3, 1]
codereviews = [2, 1, 1, 2, 3]
bugreports = [0, 0, 1, 0, 2]
internet = [3, 4, 2, 2, 5]

slices = [sum(emails), sum(codereviews), sum(bugreports), sum(internet)]
tasks = ['emails', 'codereviews', 'bugreports', 'internet']

plt.pie(slices, labels=tasks, startangle=90, autopct='%1.1f%%')

plt.title('My Cool Pie Chart')
plt.legend()
plt.show()

matplotlib percentage pie chart

饼状图现在从90度开始,也就是垂直方向。此外,我们很容易看到每项任务所占的时间比例是多少。电子邮件占用了22.2%的时间,代码审查占25%,错误报告占8.3%,互联网占44.4%。

爆炸性的切片

你可能见过饼状图,其中某一块被从饼中略去作为重音。这给了我们一个视觉上的提示,让我们可以重点关注这个数据。我们可以在matplotlib中使用explode参数来做这个。让我们把bug报告从饼中爆出来。

import matplotlib.pyplot as plt

days = [1, 2, 3, 4, 5]

emails = [1, 1, 2, 3, 1]
codereviews = [2, 1, 1, 2, 3]
bugreports = [0, 0, 1, 0, 2]
internet = [3, 4, 2, 2, 5]

slices = [sum(emails), sum(codereviews), sum(bugreports), sum(internet)]
tasks = ['emails', 'codereviews', 'bugreports', 'internet']

plt.pie(slices, labels=tasks, startangle=90,
        autopct='%1.1f%%', explode=(0, 0, 0.2, 0))

plt.title('My Cool Pie Chart')
plt.legend()
plt.show()

matplotlib pie chart explode slice

从文件中加载数据

很多时候,matplotlib被用来以图形的形式显示来自磁盘上的文件的信息,甚至可能是来自互联网的数据。让我们先来看看如何从文件中读取数据,以便在matplotlib中使用。考虑一下磁盘上这个名为fileondisk.txt的文件的例子。

python file on disk

我们有9行数据,每行有2个数据,用逗号分开。我们的目标是使用Python来读取文件,然后在matplotlib中绘制这些数据。

import matplotlib.pyplot as plt
import csv

x = []
y = []

with open('fileondisk.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='Data from fileondisk.txt')

plt.xlabel('X')
plt.ylabel('Y')
plt.title('My Cool Chart')
plt.legend()
plt.show()

matplotlib plot data from file

看起来非常酷这个例子中唯一的区别是,我们把逗号上的数据从文件中拆开。逗号左边的值被分配到x列表中,而逗号右边的值被分配到y列表中。从那里,我们知道如何使用.plot()函数来简单地在我们酷炫的图表上显示这些数据。

使用Numpy

不使用CSV阅读器,我们可以使用流行的Python库numpy来完成同样的事情。我们不需要手动打开文件并手动设置一个循环来追加每个列表,而是可以使用numpy在一行中直接将列表解压到每个变量。由此得到的图表也是一样的。

import matplotlib.pyplot as plt
import numpy as np

x, y = np.loadtxt('fileondisk.txt', delimiter=',', unpack=True)
plt.plot(x, y, label='Data from fileondisk.txt')

plt.xlabel('X')
plt.ylabel('Y')
plt.title('My Cool Chart')
plt.legend()
plt.show()

在matplotlib中绘制互联网数据图

通过互联网绘制数据的一个流行来源是股票报价。我们可以从雅虎财经下载一些数据,然后用matplotlib绘制结果。下面的代码利用urllib库从雅虎财经的API中读取数据,然后用numpy将数据解压成我们需要的变量。为了绘制结果,我们使用.plot_date()函数。

import matplotlib.pyplot as plt
import numpy as np
import urllib
import matplotlib.dates as mdates


def dateconv(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)

    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)

    return bytesconverter


def stock_data(stock):
    url = 'https://query1.finance.yahoo.com/v7/finance/download/' + stock + '?period1=1553968903&period2=1585591303&interval=1d&events=history'
    result = urllib.request.urlopen(url).read().decode()
    graph_data = []
    split_result = result.split('\n')
    for line in split_result:
        split_line = line.split(',')
        if len(split_line) == 7:
            graph_data.append(line)
    graph_data.pop(0)
    date, open, high, low, close, adjclose, volume = np.loadtxt(graph_data, delimiter=',', unpack=True,
                                                                converters={0: dateconv('%Y-%m-%d')})
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('My Cool Chart')
    plt.plot_date(date, close)
    plt.legend()
    plt.show()


stock_data('MSFT')

matplotlib yahoo finance api

Matplotlib风格

还有一件事要看,那就是在matplotlib中定制绘图的样式。Matplotlib提供了许多你可以使用的内置样式。它们包括Solarize_Light2, _classic_test_patch, bmh, classic, dark_background, fast, fivethirtyeight, ggplot, grayscale, seaborn, seaborn-bright, seaborn-colorblind, seaborn-dark, seaborn-dark-palette,seaborn-darkgrid, seaborn-deep, seaborn-muted, seaborn-notebook, seaborn-paper, seaborn-pastel, seaborn-poster, seaborn-talk, seaborn-ticks, seaborn-white, seaborn-whiteegrid, and tableau-colorblind10。下面是这些风格看起来的几个例子。

import matplotlib.pyplot as plt
import csv

x = []
y = []

with open('fileondisk.txt', 'r') as csvfile:
    plots = csv.reader(csvfile, delimiter=',')
    for row in plots:
        x.append(int(row[0]))
        y.append(int(row[1]))

plt.style.use('seaborn-dark')
plt.plot(x, y, label='Data from fileondisk.txt')

plt.xlabel('X')
plt.ylabel('Y')
plt.title('My Cool Chart')
plt.legend()
plt.show()

seaborn-dark
matplotlib seaborn-dark

bmh
matplotlib bmh style

太阳化_光明2
matplotlib solarize_light2

dark_background
dark_background matplotlib

fivethirtyeight
fivethirtyeight matplotlib

Matplotlib的XKCD模式

matplotlib的另一个很酷的功能是XKCD绘图模式。这与我们上面所做的应用样式有点不同,但这是一个非常巧妙的方法,可以使你的图形具有XKCD的草图风格。下面是如何做到这一点的。

import matplotlib.pyplot as plt
import csv

x = []
y = []

with open('fileondisk.txt', 'r') as csvfile:
    plots = csv.reader(csvfile, delimiter=',')
    for row in plots:
        x.append(int(row[0]))
        y.append(int(row[1]))
        
with plt.xkcd():
    plt.plot(x, y, label='Data from fileondisk.txt')

    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('My Cool Chart')
    plt.legend()
    plt.show()

matplotlib xkcd

在这个例子中,我们将XKCD模式和一个自定义的样式结合起来,以达到一个整洁的效果。

import matplotlib.pyplot as plt
import csv

x = []
y = []

with open('fileondisk.txt', 'r') as csvfile:
    plots = csv.reader(csvfile, delimiter=',')
    for row in plots:
        x.append(int(row[0]))
        y.append(int(row[1]))

with plt.xkcd():
    plt.style.use('dark_background')
    plt.plot(x, y, label='Data from fileondisk.txt')

    plt.xlabel('X')
    plt.ylabel('Y')
    plt.title('My Cool Chart')
    plt.legend()
    plt.show()

matplotlib xkcd and custom style

Jupyter笔记本中的Matplotlib总结

正如我们所看到的,Matplotlib是一个强大的Python库,它允许我们以各种有趣的方式查看数据。除了安装Matplotlib之外,通过利用[Jupyter Notebook],我们建立了一个用户友好的方式来测试Matplotlib所提供的所有内容。然后,我们了解了使用matplotlib的各种函数,如.plot()、.show()、.legend()、.bar()、.hist()、.scatter().stackplot()、.pie()、.plot_date()等等。