优秀的编程知识分享平台

网站首页 > 技术文章 正文

Matplotlib 3.1新功能推介(matplotlib中文手册)

nanyue 2024-10-14 11:32:21 技术文章 9 ℃

日前Python著名作图框架Matplotlib发布新版本3.1,新版本带来了那些新的功能和特性呢?今天虫虫就给大家介绍下 Matplotlib的新功能。

新功能

简洁的日期格式

默认情况下使用的自动日期格式化有点太繁杂。新版本提供一个格式化程序,用于简化时间格式化标签。

范例程序(基于Jupyter环境,下同)

%matplotlib inline

import datetime

import matplotlib.pyplot as plt

import matplotlib.dates as mdates

import numpy as np

base = datetime.datetime(2019, 2, 1)

dates = np.array([base + datetime.timedelta(hours= 2 * i)

for i in range(732)])

N = len(dates)

np.random.seed(19680801)

y = np.cumsum(np.random.randn(N))

lims = [(np.datetime64('2019-02'), np.datetime64('2019-04')),

(np.datetime64('2019-02-03'), np.datetime64('2019-02-15')),

(np.datetime64('2019-02-03 11:00'), np.datetime64('2019-02-04 13:20'))]

fig, axs = plt.subplots(3, 1, constrained_layout=True)

for nn, ax in enumerate(axs):

locator = mdates.AutoDateLocator()

formatter = mdates.ConciseDateFormatter(locator)

ax.xaxis.set_major_locator(locator)

ax.xaxis.set_major_formatter(formatter)

ax.plot(dates, y)

ax.set_xlim(lims[nn])

axs[0].set_title('Concise Date Formatter')

plt.show()

效果图如下:

辅助轴

新新版本提供两个参数Axes.secondary_xaxis和Axes.secondary_yaxis用来给现有的x,y轴增加一个辅助轴。

示例代码:

%matplotlib inline

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5, 3))

ax.plot(range(30))

ax.secondary_xaxis('top', functions=(np.deg2rad, np.rad2deg))

我们在坐标系上方(top)增加了一个新的x辅助轴,效果显示如下:

FuncScale刻度

新版本添加了一个新的FuncScale类(FuncTransform),使用它无需编写ScaleBase新子类可以实现任意比例转换,该方法的使用方法为:

ax.set_yscale('function', functions=(forward, inverse))

其中forward和inverse是返回scale变换及其逆调用。

示例代码:

def forward(a):

a = np.deg2rad(a)

return np.rad2deg(np.log(np.abs(np.tan(a) + 1.0 / np.cos(a))))

def inverse(a):

a = np.deg2rad(a)

return np.rad2deg(np.arctan(np.sinh(a)))

ax = axs[0, 1]

t = np.arange(-170.0, 170.0, 0.1)

s = t / 2.

ax.plot(t, s, '-', lw=2)

ax.set_yscale('function', functions=(forward, inverse))

ax.set_title('function: Mercator')

ax.grid(True)

ax.set_xlim([-180, 180])

ax.yaxis.set_minor_formatter(NullFormatter())

ax.yaxis.set_major_locator(FixedLocator(np.arange(-90, 90, 30)))

plt.show()

效果图如下:

自动散点图标签

新版本引入了一种新散点图创建方法已。之前,为了获取scatter()图的图例,需要绘制几个散点图,每个散点图都有一个单独的标签,或者通过创建代理图以手动显示在图例中。新版本中PathCollection新增加一个方法legend_elements(),实现以自动方式获取散点图的句柄和标签。大大简化了??散点图图例的创建。

示例代码:

%matplotlib inline

import numpy as np

import matplotlib.pyplot as plt

N = 45

x, y = np.random.rand(2, N)

c = np.random.randint(1, 5, size=N)

s = np.random.randint(10, 220, size=N)

fig, ax = plt.subplots()

scatter = ax.scatter(x, y, c=c, s=s)

legend1 = ax.legend(*scatter.legend_elements(),

loc="lower left", title="Classes")

ax.add_artist(legend1)

handles, labels = scatter.legend_elements(prop="sizes", alpha=0.6)

legend2 = ax.legend(handles, labels, loc="upper right", title="Sizes")

plt.show()

效果如下:

去除MacOSX后端应用程序

一直以来在MacOSX下matplotlin都需要使用python Framework构建才能工作。新版本去除了对该后端应用的依赖,MacOSX后端可以直接运行与非框架。该更新也同样适用于PyPy3的MacOSX后端支持。

Figure,FigureCanvas和Backends更新

Figure.frameon代理Figure.patch可见性状态

访问Figure.frameon时(通过get_frameon和set_frameon)直接转发到底层图层 artist的可见性,包括(Figure.patch.get_frameon, Figure.patch.set_frameon)。

savefig增加pil_kwargs参数

Matplotlib使用Pillow来处理JPEG和TIFF格式的保存。 savefig()函数新增加了一个pil_kwargs关键字参数,使用该参数可将参数转发给Pillow的pillow.Image.save()。

PNG图形保存时也可以使用pil_kwargs参数。此时也使用Pillow的pillow.Image.save(),而不是内置的PNG支持。

FigureCanvasBase增加Inaxes方法

FigureCanvasBase类新增加inaxes方法,用来检查一个点是否在轴中并返回最顶层的轴,否则返回None。

cairo后端默修改为pycairo而不是cairocffi

通过替换cairo的默认后端cairocffi为pycairo可以提高导入/运行时性能。如果没有安装pycairo,将还是使用cairocffi。

轴和artist类更新

axes_grid1和axisartist轴无需绘制两次

之前axis_grid1和axisartist Axes的被绘制两次才能显示,导致外观比较粗糙。

ArtistInspector.get_aliases返回类型集已更改

ArtistInspector.get_aliases以前为{fullname: {alias1: None, alias2: None, ...}}。 dict-to-None映射用于模拟早期版本的Python中的集合。它现在已被新集合取代,格式为:{fullname: {alias1, alias2, ...}}。

该值也在ArtistInspector.aliasd中使用,同步做了更改。

ConnectionPatch接受任意转换

对于诸如"data"或"axes fraction"这样的字符串,ConnectionPatch可接受任何变换作为coordsA和coordsB参数的输入。这样可以在用户定义的不同坐标系中定义的点之间绘制线段。

示例代码:

%matplotlib inline

from matplotlib.patches import ConnectionPatch

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3))

xyA = (0.2, 0.2)

xyB = (0.8, 0.8)

coordsA = "data"

coordsB = "data"

con = ConnectionPatch(xyA, xyB, coordsA, coordsB,

arrowstyle="-|>", shrinkA=5, shrinkB=5,

mutation_scale=20, fc="w")

ax1.plot([xyA[0], xyB[0]], [xyA[1], xyB[1]], "o")

ax1.add_artist(con)

xy = (0.3, 0.2)

coordsA = "data"

coordsB = "data"

con = ConnectionPatch(xyA=xy, xyB=xy, coordsA=coordsA, coordsB=coordsB,

axesA=ax2, axesB=ax1,

arrowstyle="->", shrinkB=5)

ax2.add_artist(con)

xyA = (0.6, 1.0)

xyB = (0.0, 0.2)

coordsA = "axes fraction"

coordsB = ax2.get_yaxis_transform()

con = ConnectionPatch(xyA=xyA, xyB=xyB, coordsA=coordsA, coordsB=coordsB,

arrowstyle="-")

ax2.add_artist(con)

ax1.set_xlim(0, 1)

ax1.set_ylim(0, 1)

ax2.set_xlim(0, .5)

ax2.set_ylim(0, .5)

plt.show()

效果显示如下,实现了一个跨坐标系的线段:

mplot3d Line3D支持{set,get}_data_3d

新版本中使用mplot3d中的3d投影创建的线支持使用get_data_3d()来访问数据,get_data_3d()返回包含(x,y,z)数据的array_likes元组。而set_data_3d可用于修改现有Line3D的数据。

Axes3D.voxels对结果voxels进行着色

voxels()方法默认shade参数改True。它会根据方向调整阴影,其行为与trisurf()以及bar3d()的匹配参数相同。

示例代码:

%matplotlib inline

import matplotlib.pyplot as plt

import numpy as np

x, y, z = np.indices((8, 8, 8))

cube1 = (x < 3) & (y < 3) & (z < 3)

cube2 = (x >= 5) & (y >= 5) & (z >= 5)

link = abs(x - y) + abs(y - z) + abs(z - x) <= 2

voxels = cube1 | cube2 | link

colors = np.empty(voxels.shape, dtype=object)

colors[link] = 'red'

colors[cube1] = 'blue'

colors[cube2] = 'green'

fig = plt.figure(figsize=plt.figaspect(0.5))

ax, ax_shaded = fig.subplots(1, 2, subplot_kw=dict(projection='3d'))

ax.voxels(voxels, facecolors=colors, edgecolor='k', shade=False)

ax.set_title("Unshaded")

ax_shaded.voxels(voxels, facecolors=colors, edgecolor='k', shade=True)

ax_shaded.set_title("Shaded (default)")

plt.show()

效果图如下:

轴和刻度

添加了Axis.get_inverted和Axis.set_inverted

Axis.get_inverted和Axis.set_inverted方法用于查询并设置轴是否使用"反向"方向(即,x轴向左增加,y轴向下增加)。

其效果类似于Axes.xaxis_inverted,Axes.yaxis_inverted,Axes.invert_xaxis以及Axes.invert_yaxis。

具体的区别是Axes..set_inverted可以是轴反转更容易,不要考虑之前反转状态。

默认次要刻度线间距

对于间隔2.5个单位的主要刻度间隔,默认次刻度间隔从0.625变为0.5。

EngFormatter新增加 usetex,useMathText关键字参数

EngFormatter中添加了一个公共API,用于控制如何呈现ticklabels中的数字。默认情况下,useMathText的值为rcParams["axes.formatter.use_mathtext'"] usetex的值rcParams["'text.usetex'"].rcParams。

如果其中任何一个为True,则数字将由$signs封装。在使用TeX时,该设置导致数字会以TeX的数学字体显示。使用mathtext时,数字周围的$符号将确保unicode呈现。这回保证使用mathtext时减号被渲染为unicode=minus (U+2212)。

动画和互动

支持前进/后退鼠标按钮

图管理器在新版本中增加对鼠标按钮的button_press事件支持,效果类似于key_press事件。可以自定义对鼠标按钮进行绑定操作。

save()增加progress_callback参数

Animation.save方法新增加一个可选的progress_callback参数来通知保存进度。

animation.FuncAnimation中增加cache_frame_data关键字

matplotlib.animation.FuncAnimation默认缓存帧数据;但是,有些情况下,缓存效果不好,例如当需要以交互方式绘制(未保存)FuncAnimation时,帧数据所需的内存非常大。通过添加cache_frame_data关键字参数,用户可以自行禁用该缓存。

使用PillowWriter无限循环GIF

我们承认大多数人都想不止一次看gif。可使用PillowWriter将动画保存为gif可以生成无限循环的gif动画。

matplotlib.widgets.Slider支持垂直方向

matplotlib.widgets.Slider小部件现在采用可选的参数方向,指示滑块应采用的方向(支持"水平"或"垂直")。

修正光标点图像值的显示格式

当存在颜色条时,状态栏中显示鼠标光标所在点的图像值。例如,对于显示值10,000和10,001的图像,状态栏(使用默认设置)将值显示为10000和10001),而这两个值先前显示为1e+04.。

MouseEvent按钮属性现在是IntEnum

MouseEvent实例的button属性可以取值None,1(左按钮),2(中间按钮),3(右按钮),"up"(滚动)以及"向下"(滚动)。为了增加易用性,现在使用IntEnum 类matplotlib.backend_bases.MouseButton来表示1,2和3的值,其值为MouseButton.LEFT(== 1),MouseButton.MIDDLE(== 2)和MouseButton.RIGHT (== 3)。

配置更新

MATPLOTLIBRC环境变量可指向任何"文件"路径

可以将MATPLOTLIBRC路径可以支持任何文件,包括设备文件,比如在*nix操作系统下,可将MATPLOTLIBRC设置为/dev/ null来忽略用户的matplotlibrc文件,使用Matplotlib的默认值。

注意,如果MATPLOTLIBRC指向一个目录,Matplotlib将尝试从$MATPLOTLIBRC/ matplotlibrc加载matplotlibrc文件。

MATPLOTLIBRC文件中允许使用LaTeX代

以前,使用逗号作为分隔符解析rc文件rcParams["pgf.preamble"] 和rcParams["text.latex.preamble"]。会导致LaTeX有效的代码的破坏,比如:

\usepackage[protrusion=true, expansion=false]{microtype}

新版本中修改解析可将完整行传递给LaTeX系统,并保留所有逗号。从Python脚本中传递字符串列表仍然可以像以前一样工作。

新的日志记录API

可以调用matplotlib.set_loglevel / pyplot.set_loglevel来显示更详细的日志记录输出。

总结

本文介绍了Matplotlib新发布的版本3.1的功能更新,欢迎大家升级新版本并尝试各种新功能。其升级也非常简单,可以用pip一键升级:

pip install --upgrade Matplotlib

Tags:

最近发表
标签列表