0

0

在Sphinx doctest中处理Matplotlib图形示例的策略

碧海醫心

碧海醫心

发布时间:2025-12-02 11:06:08

|

865人浏览过

|

来源于php中文网

原创

在sphinx doctest中处理matplotlib图形示例的策略

本文探讨了在Sphinx doctest中使用包含Matplotlib图形示例的文档字符串时,如何避免因`plt.show()`导致的测试阻塞问题。核心策略是优化Matplotlib绘图函数,使其接受可选的`ax`参数,并将图形显示逻辑(`plt.show()`)从函数内部移除,从而允许doctest在非交互模式下顺利运行,并提升函数的可重用性与灵活性。

解决Sphinx doctest中Matplotlib图形阻塞问题

在Python项目中使用Sphinx生成文档并利用其doctest功能进行代码示例验证是一种高效实践。然而,当函数的文档字符串中包含Matplotlib绘图示例,并且函数内部调用了plt.show()时,doctest在执行这些示例时会因图形窗口的弹出而暂停,需要手动关闭窗口才能继续,这极大地影响了自动化测试流程。本教程将详细介绍如何通过优化Matplotlib绘图函数来解决这一问题。

1. 问题根源分析

原始的绘图函数通常会直接在函数内部创建图形并调用plt.show()来显示它。例如,考虑以下函数:

import matplotlib.pyplot as plt

def plot_numbers_original(x):
    """
    显示一组数字的折线图。

    Parameters
    ----------
    x : list
        要绘制的数字列表。

    Example
    -------
    >>> import your_module_name # 假设函数位于 your_module_name 模块中
    >>> x = [1, 2, 5, 6, 8.1, 7, 10.5, 12]
    >>> your_module_name.plot_numbers_original(x)
    """
    _, ax = plt.subplots()
    ax.plot(x, marker="o", mfc="red", mec="red")
    ax.set_xlabel("Label for x-axis")
    ax.set_ylabel("Label for y-axis")
    ax.set_title("Title of the plot")

    plt.show() # 这一行是导致doctest阻塞的根源

当Sphinx make doctest命令执行到your_module_name.plot_numbers_original(x)时,plt.show()会被调用,弹出一个Matplotlib图形窗口。在非交互式或自动化测试环境中,这个窗口不会自动关闭,导致测试进程挂起,需要用户手动干预才能继续。这与自动化测试的初衷相悖。

2. 优化Matplotlib绘图函数

解决此问题的核心策略是将绘图逻辑与图形显示逻辑解耦。具体做法是让绘图函数接受一个可选的Matplotlib Axes 对象作为参数。如果用户提供了Axes对象,函数就在该对象上绘图;如果未提供,函数则自行创建一个新的Figure和Axes。最重要的是,从函数内部移除plt.show()的调用。

白瓜AI
白瓜AI

白瓜AI,一个免费图文AI创作工具,支持 AI 仿写,图文生成,敏感词检测,图片去水印等等。

下载

以下是优化后的函数示例:

import matplotlib.pyplot as plt

def plot_numbers(x, *, ax=None):
    """
    显示一组数字的折线图。

    Parameters
    ----------
    x : list
        要绘制的数字列表。
    ax : matplotlib.axes.Axes, optional
        可选的Matplotlib Axes对象,用于在该坐标轴上绘图。
        如果未提供,函数将创建一个新的Figure和Axes。

    Example
    -------
    >>> import your_module_name # 假设函数位于 your_module_name 模块中
    >>> x = [1, 2, 5, 6, 8.1, 7, 10.5, 12]
    >>> result_ax = your_module_name.plot_numbers(x)
    >>> # 在doctest中,我们通常不显示图形。我们可以验证函数是否正确地设置了坐标轴属性。
    >>> len(result_ax.lines) # 验证图中绘制的线条数量
    1
    >>> result_ax.get_xlabel() # 验证x轴标签
    'Label for x-axis'
    >>> result_ax.get_title() # 验证图表标题
    'Title of the plot'

    >>> # 如果需要在交互式环境或特定测试中显示图形,可以这样做:
    >>> # fig, my_ax = plt.subplots()
    >>> # your_module_name.plot_numbers(x, ax=my_ax)
    >>> # plt.show() # 在需要显示时由外部调用
    """
    if ax is None:
        _, ax = plt.subplots() # 如果没有提供ax,则创建一个新的Figure和Axes

    ax.plot(x, marker="o", mfc="red", mec="red")
    ax.set_xlabel("Label for x-axis")
    ax.set_ylabel("Label for y-axis")
    ax.set_title("Title of the plot")

    return ax # 返回Axes对象,以便外部进行进一步操作或显示

关键改动点:

  1. ax=None 参数引入: 函数现在接受一个可选的ax参数,其类型应为matplotlib.axes.Axes。
  2. 条件性plt.subplots(): 只有当ax未提供时,函数才会在内部调用plt.subplots()来创建一个新的图形和坐标轴。这确保了函数既可以独立使用,也可以作为更大绘图流程的一部分。
  3. 移除plt.show(): 最重要的一点是,plt.show()被完全从函数内部移除。这意味着函数本身不再负责显示图形,而是将显示控制权交由调用者。
  4. 返回ax对象: 函数现在返回它所操作的Axes对象。这允许调用者在函数执行后,对该Axes对象进行进一步的自定义或决定何时显示、保存图形。

3. 优化后的优势

这种重构带来了多方面的好处,显著提升了代码质量和开发效率:

  • Sphinx Doctest兼容性: 由于plt.show()不再在函数内部被调用,doctest在执行示例时不会弹出图形窗口,从而避免了阻塞,实现了自动化测试流程。
  • 更高的灵活性和可重用性:
    • 组合绘图: 用户可以将多个绘图函数的输出绘制到同一个Axes对象上,轻松实现复杂的组合图或子图布局。
    • 外部控制: 调用者可以完全控制图形的生命周期和显示方式(例如,保存到文件、嵌入到GUI应用中,或在交互式会话中显示)。
    • 符合设计模式: 这符合Matplotlib推荐的“辅助函数”(helper functions)设计模式,即函数应该只负责绘图,而不负责图形的创建和显示。
  • 非交互式测试友好: 无论是doctest还是其他单元测试框架,都可以在不产生任何图形界面的情况下测试绘图逻辑,从而提高测试效率和稳定性。

4. 注意事项与最佳实践

  • 何时调用 plt.show(): plt.show()通常应该在脚本的顶层,或者在交互式会话的末尾调用,当你准备好显示所有图形时。在库函数或模块内部调用它会限制其灵活性,并可能导致上述测试问题。
  • 图形关闭: 在自动化测试环境中,即使没有plt.show(),如果测试过程中创建了

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

758

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

639

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

761

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

618

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1264

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

548

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

708

2023.08.11

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 2万人学习

Django 教程
Django 教程

共28课时 | 3.1万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号