操作方法#

为什么我有这么多滴答声,和/或为什么它们不正常?#

意外滴答行为的一个常见原因是传递字符串列表而不是数字或日期时间对象。在读取以逗号分隔的文本文件时,这很容易发生,恕不另行通知。Matplotlib 将字符串列表视为分类变量(Plotting categorical variables),默认情况下每个类别打一个勾,并按照提供的顺序绘制它们。

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(1, 2, constrained_layout=True, figsize=(6, 2))

ax[0].set_title('Ticks seem out of order / misplaced')
x = ['5', '20', '1', '9']  # strings
y = [5, 20, 1, 9]
ax[0].plot(x, y, 'd')
ax[0].tick_params(axis='x', labelcolor='red', labelsize=14)

ax[1].set_title('Many ticks')
x = [str(xx) for xx in np.arange(100)]  # strings
y = np.arange(100)
ax[1].plot(x, y)
ax[1].tick_params(axis='x', labelcolor='red', labelsize=14)

源代码png

../../_images/howto_faq-1.png

解决方案是将字符串列表转换为数字或日期时间对象(通常为或 )。np.asarray(numeric_strings, dtype='float')np.asarray(datetime_strings, dtype='datetime64[s]')

有关更多信息,请参阅修复过多的刻度

确定图中 Artists 的范围#

有时我们想知道艺术家的程度。MatplotlibArtist对象有一个方法,该方法Artist.get_window_extent通常会以像素为单位返回艺术家的范围。但是,某些艺术家,尤其是文本,必须至少渲染一次才能知道其范围。Matplotlib 提供 Figure.draw_without_rendering,应该在调用之前调用 get_window_extent

检查一个图是否为空#

空实际上可能意味着不同的东西。该图是否包含任何艺术家?一个为空的图形是否Axes仍算为空?如果渲染为纯白色,图形是否为空(可能有艺术家在场,但他们可能在绘图区域之外或透明)?

出于这里的目的,我们将空定义为:“该图不包含任何艺术家,除了它的背景补丁。” 背景的例外是必要的,因为默认情况下,每个图形都包含一个Rectangle背景补丁。可以通过以下方式检查此定义:

def is_empty(figure):
    """
    Return whether the figure contains no Artists (other than the default
    background patch).
    """
    contained_artists = figure.get_children()
    return len(contained_artists) <= 1

我们决定不将其作为图形方法包含在内,因为这只是定义空的一种方法,并且很少需要检查上述内容。通常处理图形的用户或程序知道他们是否在图形中添加了一些东西。

除非通过实际渲染图形并调查渲染结果,否则无法可靠地检查图形是否会呈现为空。

查找特定类型图形中的所有对象#

每个 Matplotlib 艺术家(请参阅艺术家教程)都有一个调用方法,该方法findobj()可用于递归搜索艺术家以查找它可能包含的任何满足某些条件的艺术家(例如,匹配所有Line2D 实例或匹配某个任意过滤器函数)。例如,下面的代码片段会在图中找到每个具有 set_color属性的对象并将对象设为蓝色:

def myfunc(x):
    return hasattr(x, 'set_color')

for o in fig.findobj(myfunc):
    o.set_color('blue')

您还可以过滤类实例:

import matplotlib.text as text
for o in fig.findobj(text.Text):
    o.set_fontstyle('italic')

防止刻度标签有偏移量#

默认格式化程序将使用偏移量来减少刻度标签的长度。要在每个轴的基础上关闭此功能:

ax.get_xaxis().get_major_formatter().set_useOffset(False)

设置rcParams["axes.formatter.useoffset"](默认值:)True,或使用不同的格式化程序。详情请参阅ticker

保存透明数字#

savefig()命令有一个关键字参数 透明,如果为“真”,则在保存时将使图形和轴背景透明,但不会影响屏幕上显示的图像。

如果您需要更细粒度的控制,例如,您不想要完全透明或想要影响屏幕显示的版本,您可以直接设置 alpha 属性。该图形有一个 Rectangle名为patch的实例,轴有一个名为patch 的 Rectangle 实例。您可以直接在它们上设置任何属性(facecoloredgecolorlinewidthlinestylealpha)。例如:

fig = plt.figure()
fig.patch.set_alpha(0.5)
ax = fig.add_subplot(111)
ax.patch.set_alpha(0.5)

如果您需要所有图形元素都是透明的,目前没有全局 alpha 设置,但您可以在单个元素上设置 alpha 通道,例如:

ax.plot(x, y, alpha=0.5)
ax.set_xlabel('volts', alpha=0.5)

将多个绘图保存到一个 pdf 文件中#

许多图像文件格式每个文件只能有一个图像,但有些格式支持多页文件。目前,Matplotlib 仅通过 backend_pdf.PdfPagesbackend_pgf.PdfPages类使用 pdf 或 pgf 后端为 pdf 文件提供多页输出。

为刻度标签腾出空间#

默认情况下,Matplotlib 在子图周围使用固定百分比边距。这可能导致标签在图形边界重叠或被切断。有多种方法可以解决此问题:

跨多个子图对齐我的 ylabels #

如果您有多个相互重叠的子图,并且 y 数据具有不同的比例,您通常会得到 ylabels 在多个子图中没有垂直对齐,这可能没有吸引力。默认情况下,Matplotlib 定位 ylabel 的 x 位置,使其不与任何 y 刻度重叠。您可以通过指定标签的坐标来覆盖此默认行为。下面的示例显示了左侧子图中的默认行为,以及右侧子图中的手动设置。

../../_images/sphx_glr_align_ylabels_001.png

控制绘图元素的绘制顺序#

绘图元素的绘制顺序以及哪些元素将在顶部由set_zorder属性确定。有关详细说明,请参阅Zorder 演示

使绘图的纵横比相等#

Axes 属性set_aspect()控制轴的纵横比。您可以将其设置为 'auto'、'equal' 或控制比率的某个比率:

ax = fig.add_subplot(111, aspect='equal')

有关完整示例,请参见等轴纵横比

绘制多个 y 轴刻度#

一个常见的要求是为左右 y 轴设置两个刻度,这是可以使用的twinx()(目前不支持两个以上的刻度,尽管它在愿望清单上)。这工作得很好,尽管当您尝试交互式平移和缩放时有一些怪癖,因为两个比例都没有得到信号。

该方法使用twinx()(及其姐妹 twiny())使用2 个不同的 axes ,在第二个轴上关闭轴矩形框以防止它遮挡第一个轴,并根据需要手动设置刻度位置和标签。您可以根据需要使用单独matplotlib.ticker的格式化程序和定位器,因为这两个轴是独立的。

源代码png

../../_images/howto_faq-2.png

有关完整示例,请参阅具有不同比例的绘图。

在不出现窗口的情况下生成图像#

干脆不调用show,直接把图保存成想要的格式:

import matplotlib.pyplot as plt
plt.plot([1, 2, 3])
plt.savefig('myfig.png')

也可以看看

嵌入 Web 应用程序服务器 (Flask)以获取有关在 Web 应用程序内运行 matplotlib 的信息。

使用线程#

Matplotlib 不是线程安全的:事实上,存在影响某些艺术家的已知竞争条件。因此,如果您使用线程,您有责任设置适当的锁来序列化对 Matplotlib 艺术家的访问。

您也许可以从不同的线程处理不同的图形。但是,在这种情况下,您必须使用非交互式后端(通常是 Agg),因为大多数 GUI 后端也需要从主线程运行。