Matplotlib 自定义单位

PythonPythonBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

Matplotlib 是一个用于 Python 编程语言的绘图库。它提供了一个面向对象的 API,用于使用 Tkinter、wxPython、Qt 或 GTK 等通用 GUI 工具包将绘图嵌入应用程序中。Matplotlib 允许开发者在 Python 中创建各种静态、动画和交互式可视化。

在本实验中,我们将学习如何在 Matplotlib 中创建自定义单位,并使用这些自定义单位绘制数据。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。

导入库

第一步,我们需要导入所需的库——matplotlib.pyplotnumpymatplotlib.tickermatplotlib.units

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.units as units

创建一个自定义单位类

在这一步中,我们将创建一个自定义单位类——Foo。这个类将支持转换以及根据“单位”进行不同的刻度格式化。这里,“单位”仅仅是一个标量转换因子。

class Foo:
    def __init__(self, val, unit=1.0):
        self.unit = unit
        self._val = val * unit

    def value(self, unit):
        if unit is None:
            unit = self.unit
        return self._val / unit

创建一个转换器类

在这一步中,我们将创建一个转换器类——FooConverter。这个类将定义三个静态方法——axisinfoconvertdefault_units

class FooConverter(units.ConversionInterface):
    @staticmethod
    def axisinfo(unit, axis):
        """返回 Foo 轴信息。"""
        if unit == 1.0 或 unit == 2.0:
            return units.AxisInfo(
                majloc=ticker.IndexLocator(8, 0),
                majfmt=ticker.FormatStrFormatter("VAL: %s"),
                label='foo',
                )

        else:
            return None

    @staticmethod
    def convert(obj, unit, axis):
        """
        使用 *unit* 转换 *obj*。

        如果 *obj* 是一个序列,返回转换后的序列。
        """
        if np.iterable(obj):
            return [o.value(unit) for o in obj]
        else:
            return obj.value(unit)

    @staticmethod
    def default_units(x, axis):
        """返回 *x* 的默认单位或 None。"""
        if np.iterable(x):
            for thisx in x:
                return thisx.unit
        else:
            return x.unit

注册自定义单位类

在这一步中,我们将把自定义单位类——Foo——与转换器类——FooConverter——进行注册。

units.registry[Foo] = FooConverter()

创建数据点

在这一步中,我们将使用自定义单位类——Foo——创建一些数据点。

## 创建一些 Foo 对象
x = [Foo(val, 1.0) for val in range(0, 50, 2)]
## 以及一些任意的 y 数据
y = [i for i in range(len(x))]

创建图表

在这一步中,我们将创建两个图表——一个使用自定义单位,另一个使用默认单位。

fig, (ax1, ax2) = plt.subplots(1, 2)
fig.suptitle("Custom units")
fig.subplots_adjust(bottom=0.2)

## 绘制时指定单位
ax2.plot(x, y, 'o', xunits=2.0)
ax2.set_title("xunits = 2.0")
plt.setp(ax2.get_xticklabels(), rotation=30, ha='right')

## 绘制时不指定单位;将使用 axisinfo 的 None 分支
ax1.plot(x, y)  ## 使用默认单位
ax1.set_title('default units')
plt.setp(ax1.get_xticklabels(), rotation=30, ha='right')

plt.show()

运行代码

在最后一步中,运行代码以创建自定义单位图表。

总结

在本实验中,我们学习了如何使用自定义单位类和转换器类在Matplotlib中创建自定义单位。然后,我们创建了两个图表——一个使用自定义单位,另一个使用默认单位——以演示这些自定义单位的用法。在处理需要自定义缩放或刻度格式的复杂数据时,自定义单位可能会很有用。