Matplotlib快速入门

这个教程包含了些基础的用法示例和练习,可以帮助您很快熟悉Matplotlib。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

一个简单示例

Matplotlib 将您的数据绘制在Figures(画布)上,每一张画布上可以包含一个或多个Axes(坐标系,您可以把坐标(x,y)显示在Axes中,极坐标中的(theta,r),3D坐标的(x,y,z)等)。创建带坐标系的图形的最简单的方法是使作pyplot.subplots(),然后就可以用Axes.plot()方法来在坐标轴上绘制数据。

fig,ax = plt.subplots() #创建一张画布,上面有一个坐标系
ax.plot([1,2,3,4],[1,4,2,3]) # 往坐标系上绘制数据

[]

png

Figure的结构

Figure统筹了所有的子坐标系,那是一组特殊的Artists(包含标题、图例、色条等),甚至嵌套的subfigures。 创建新Figure最简单的方法是用pyplot,如:

fig1 = plt.figure() # 一个没有坐标系的空画布,不显示
fig2,ax = plt.subplots() # 包含一个坐标系的画布
fig3,axs = plt.subplots(2,2) # 包含2*2坐标系阵列的画布

png

png

将轴与图形一起创建是很方便,但可能不够灵活,您也可以后期手动添加坐标系,要注意,很多Matplotlib后端支持缩放和平移。

Axes

Axes坐标系,可以把它当成一个Artist(画家,我感觉画纸可能更贴切一些),把他绑定到画板(Figure)上,它包含一个可以画图的区域,一般包含2个(3D图的话是3个)Axis(数轴)对象,Axis对象(注意和Axes对象区别,一个是数轴,一个是坐标系)提供了ticks和tick labels来显示坐标轴的刻度,每个Axes坐标系也有一个title(通过set_title()方法来设置),一个x-label(通过set_xlabel()设置),一个y-label(通过set_ylabel()方法来设置)。

Axes类及其成员函数是使用OOP接口的主要入口,里面定义了大多数的绘图方法,比如ax.plot()

Axis

Axis对象设置比例尺和数值范围,生成标记(ticks,轴上的记号)和标记名(ticklabels,标记记号的字符串),记号的位置由Locator对象确定,标记名字符串由Formatter格式化。正确地组合使用Locator和Formatter可以精准控制刻度位置和标签。 ## Artist 基本上,Figure上所有的可见对象都是Aritst(甚至Figure,Axes,Axis对象也是),主要包括Text对象,Line2D对象,collections对象,Patch对象等,当Figure开始渲染时,所有的Aritst都被绘制到Axes上,这些Artist不能被其他坐标系共享,也不能从一个坐标系移动到另一个。

输入绘图函数的参数类型

绘图函数需要numpy.array 或者 numpy.ma.masked_array作为输入参数,或者可以传入numpy.asarray的参数,类似数组的类,如pandas数据对象和numpy.matrix对象可能无法按预期工作。常用的作法是绘图前将它们转换成numpy.array对象,比如转化成mumpy.matrix

b = np.matrix([[1,2],[3,4]])
b_asarray = np.asarray(b)

大多数的对象也会解析一个可寻址对象,比如dict,numpy.recarray,pandas.DataFrame。Matplotlib允许您提供数据关键字参数并生成对应于x和y变量的字符串的图象

np.random.seed(19680801)
data = {'a':np.arange(50),
'c':np.random.randint(0,50,50),
'd':np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
fig,ax = plt.subplots(figsize=(5,2.7),layout='constrained')
ax.scatter('a','b',c='c',s='d',data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b')

Text(0, 0.5, 'entry b')

png

编码样式

显式和隐式接口

如上所述,有两种方法可以使用Matplotlib 1. 显式创建Figures和Axes,并调用它们的方法(面向对象的方法)。 2. 依靠pyplot隐式创建和管理Figures和Axes,并使用pyplot的函数进行绘图。

面向对象方法的例子

x = np.linspace(0, 2, 100) # Sample data.
# 注意,即使是面向对象的风格,我们也用matplotlib.pyplot.figure来创建Figure
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear') # 往坐标轴上画数据.
ax.plot(x, x**2, label='quadratic') # ...
ax.plot(x, x**3, label='cubic') # ... .
ax.set_xlabel('x label') # 设置X轴标记.
ax.set_ylabel('y label') # 设置Y轴标记.
ax.set_title("Simple Plot") # 设置坐标轴标题.
ax.legend() # 增加图例.

png

pyplot的例子

x = np.linspace(0,2,100)
plt.figure(figsize=(5,2.7),layout = 'constrained')
plt.plot(x,x,label = 'linear')
plt.plot(x,x**2,label = 'quadratic')
plt.plot(x,x**3,label = 'cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title('simple plot')
plt.legend()

png

Matplotlib的文档和示例同时使用面向对象的OO和pyplot样式。一般来说,我们建议使用OO风格,尤其是对于复杂的绘图以及打算作为大型项目的一部分重用的函数和脚本。然而,pyplot样式对于快速交互工作非常方便。大家可以根据实践需要来选择。

代码复用

如果您需要使用不同的数据集反复绘制相同的绘图,或者想要轻松包装Matplotlib的方法,可以使用下面的自定义函数

def my_plotter(ax,data1,data2,param_dict):
out = ax.plot(data1,data2,**param_dict)
return out
# 例如:
data1, data2, data3, data4 = np.random.randn(4, 100) # make 4 random data sets
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.7))
my_plotter(ax1, data1, data2, {'marker': 'x'})
my_plotter(ax2, data3, data4, {'marker': 'o'})

[]

png

大多数的绘图方法都有样式选项,这些选项可以在调用plotting方法时调用,或者在Artist中的”setter“中访问。在下边的绘图中,我们手动设置颜色、线宽、和线的样式,然后使用set_lifestyle设置第二行的线条样式。

fig,ax = plt.subplots(figsize=(5,2.7))
x = np.arange(len(data1))
ax.plot(x,np.cumsum(data1),color='blue',linewidth=3,linestyle = '--')
l, = ax.plot(x,np.cumsum(data2),color='orange',linewidth=2)
l.set_linestyle(':')

png

Matplotlib 有一个非常灵活的颜色阵列,大多数艺术家都接受它;有关规格列表,请参阅颜色教程。有些艺术家会采用多种颜色。即对于散点图,标记的边缘可以是与内部不同的颜色:

fig, ax = plt.subplots(figsize=(5,2.7))
ax.scatter(data1,data2,s=50,facecolor='C0',edgecolor='k')

png

线宽、线型和标记

Matplotlib的线宽用印刷点来表示(1pt=1/72英寸),可用于描边,类拟地,描边线可以具有自己的线条样式。

Marker size标记的大小取决与所使用的方法,plot以点为单位指定标记的大小,一般来说是Marker的直径或宽度。

scatter指定标记大小与标记的可视区域大致成比例。

一些常用的标记样式Matplotlib已将其设置为字符串代码,当然,用户也可以自定义自已的标记样式。

fig,ax = plt.subplots(figsize=(5,2.7))
ax.plot(data1,'o',label='data1')
ax.plot(data2,'d',label='data2')
ax.plot(data3,'v',label='data3')
ax.plot(data4,'s',label='data4')
ax.legend()

png

给图贴标签

Axes的标签和文本

set_xlabel、set_ylabel和set_title用于在指定位置添加文本。也可以使用文本将文本直接添加到绘图中:

mu,sigma = 115,15
x = mu + sigma*np.random.randn(10000)
fig,ax = plt.subplots(figsize=(5,2.7),layout='constrained')
# 柱状图的数据
n,bins,patches = ax.hist(x,50,density=True,facecolor='C0',alpha=0.75)
ax.set_xlabel('Length')
ax.set_ylabel('probability')
ax.set_title('Aardvark lengths (not really)')
ax.text(75,.025, r'$mu=115, sigma=15#39;)
ax.axis([55,175,0,0.03])

(55.0, 175.0, 0.0, 0.03)

png

所有的text函数返回一个matplotlib.text.Text实例,您也可以通过向text函数中传入关键字参数来自定义特性。

t = ax.set_xlabel('my data',fontsize = 14,color='red')

在文本中使作数学表达式

Matplotlib 接受Tex方程表达式。如:

ax.set_title(r'$sigma_i=15#39;)

Text(0.5, 1.0, '$sigma_i=15#39;)

我们还可以给绘图填加注释

fig,ax = plt.subplots(figsize=(5,2.7))
t = np.arange(0.0,5.0,0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t,s,lw=2)
ax.annotate('local max',
xy=(2,1),
xytext=(3,2),
arrowprops=dict(facecolor='black',shrink=0.05))
# xy是箭头指向的图中的数据点
# xytext是文本开始的数据点,也是箭尾指向的数据点
ax.set_ylim(-2,2)

(-2.0, 2.0)

png

有时,为了便于用户理解,我们常常给图加上图例。

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(np.arange(len(data1)), data1, label='data1')
ax.plot(np.arange(len(data2)), data2, label='data2')
ax.plot(np.arange(len(data3)), data3, 'd', label='data3')
ax.legend()

png

坐标系风格和标尺

每一个坐标系Axis都有两个或三个数轴(Axis)对象对应x轴和y轴(以及z轴),它们控制了Axis的风格,标尺的位置和标尺的格式。

除了线性比例,Matplotlib还提供了非线性比例,比如对数比例,如loglog,semilogx,semilogy。这里我们手动设一下比例尺。

fig, axs = plt.subplots(1, 2, figsize=(5, 2.7), layout='constrained')
xdata = np.arange(len(data1)) # make an ordinal for this
data = 10**data1
axs[0].plot(xdata, data)
axs[1].set_yscale('log')
axs[1].plot(xdata, data)

[]

png

fig, axs = plt.subplots(2, 1, layout='constrained')
axs[0].plot(xdata, data1)
axs[0].set_title('Automatic ticks')
axs[1].plot(xdata, data1)
axs[1].set_xticks(np.arange(0, 100, 30), ['zero', '30', 'sixty','90']) #第一个是ticket,第二个是label,前后一一对应的关系
axs[1].set_yticks([-1.5, 0, 1.5]) # note that we don't need to specify labels
axs[1].set_title('Manual ticks')

Text(0.5, 1.0, 'Manual ticks')

png

日期字符串

Matplotlib可以处理日期数组、字符串数组以及浮点数的绘制。它们会根据需要获得特殊的标尺和标签。对于日期:

fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
dates = np.arange(np.datetime64('2021-11-15'), np.datetime64('2021-12-25'),
np.timedelta64(1, 'h'))
data = np.cumsum(np.random.randn(len(dates)))
ax.plot(dates, data)
cdf = mpl.dates.ConciseDateFormatter(ax.xaxis.get_major_locator())
ax.xaxis.set_major_formatter(cdf)

png

关于分类绘图需要注意的一点是,某些分析文本文件的方法会返回字符串列表,即使字符串都表示数字或日期。如果您传递1000个字符串,Matplotlib将认为您是指1000个类别,并将为您的绘图添加1000个刻度!

一些其他的轴对像

在一个图表中绘制不同单位或大小的数据可能需要额外的y轴。这种情况可以通过使用twinx添加一个新的轴来创建,该轴具有一个不可见的x轴和一个位于右侧的y轴(类似于twiny)。如图:

fig, (ax1, ax3) = plt.subplots(1, 2, figsize=(7, 2.7), layout='constrained')
l1, = ax1.plot(t, s)
ax2 = ax1.twinx()
l2, = ax2.plot(t, range(len(t)), 'C1')
ax2.legend([l1, l2], ['Sine (left)', 'Straight (right)'])
ax3.plot(t, s)
ax3.set_xlabel('Angle [rad]')
ax4 = ax3.secondary_xaxis('top', functions=(np.rad2deg, np.deg2rad))
ax4.set_xlabel('Angle [°]')

Text(0.5, 0, 'Angle [°]')

png

有时候我们想在二维图中表现三维的信息,我们希望在一个由颜色图中的颜色表示的绘图中有一个第三维度。Matplotlib有许多绘图类型可以做到这一点:

X, Y = np.meshgrid(np.linspace(-3, 3, 128), np.linspace(-3, 3, 128))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
fig, axs = plt.subplots(2, 2, layout='constrained')
pc = axs[0, 0].pcolormesh(X, Y, Z, vmin=-1, vmax=1, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[0, 0])
axs[0, 0].set_title('pcolormesh()')
co = axs[0, 1].contourf(X, Y, Z, levels=np.linspace(-1.25, 1.25, 11))
fig.colorbar(co, ax=axs[0, 1])
axs[0, 1].set_title('contourf()')
pc = axs[1, 0].imshow(Z**2 * 100, cmap='plasma',
norm=mpl.colors.LogNorm(vmin=0.01, vmax=100))
fig.colorbar(pc, ax=axs[1, 0], extend='both')
axs[1, 0].set_title('imshow() with LogNorm()')
pc = axs[1, 1].scatter(data1, data2, c=data3, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[1, 1], extend='both')
axs[1, 1].set_title('scatter()')

Text(0.5, 1.0, 'scatter()')

png

多画板和多轴模式

您可以使用fig = plt.figure()或者fig2,ax=plt.subplots()方法打开多个画板(Figures),在保留对象引用的前提下,您可以向任一画板添加画家(Artists)。

您可以通过多种方法来添加坐标系,但最基础的方法还是上面用过的plt.subplots(),要想实现更复杂的布局,如跨行列的布局,可以用subplot_mosaic()方法。

fig,axd = plt.subplot_mosaic([['upleft','right'],['lowleft','right']],
layout = 'constrained')
axd['upleft'].set_title('upleft')
axd['lowleft'].set_title('lowleft')
axd['right'].set_title('right')

Text(0.5, 1.0, 'right')

png

展开阅读全文

页面更新:2024-04-12

标签:坐标轴   坐标系   画布   字符串   样式   函数   标记   入门   对象   快速   方法   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top