欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

matplotlib 之 pyplot 中常用方法的源码调用过程(plt.plot、plt.scatter、plt.hist、plt.bar、plt.show、plt.savefig)

程序员文章站 2022-07-13 21:51:01
...

____tz_zs

关于这些方法的使用见 matplotlib 模块的简单使用 ,本文是关于这些方法在源码中的调用过程,用以加深对matplotlib库的理解。

 

plt.plot、plt.scatter、plt.hist、plt.bar 等

plt.plot、plt.scatter、plt.hist、plt.bar 等方法均调用 gcf() 获取 figure 对象,然后调用 figure 的 gca() 方法获取 axes 对象(如果没有 axes 则使用 self.add_subplot(1, 1, 1, **kwargs) 创建)。然后使用 axes.方法名 绘制相应的图。

1、调用同模块下的 ax = gca() 方法,获取 axes 对象。再使用 axes 绘制相应的图

pyplot.py

    # This function was autogenerated by boilerplate.py.  Do not edit as
    # changes will be lost
    @_autogen_docstring(Axes.plot)
    def plot(*args, **kwargs):
        ax = gca()
        # Deprecated: allow callers to override the hold state
        # by passing hold=True|False
        washold = ax._hold
        hold = kwargs.pop('hold', None)
        if hold is not None:
            ax._hold = hold
            from matplotlib.cbook import mplDeprecation
            warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
                          mplDeprecation)
        try:
            ret = ax.plot(*args, **kwargs)
        finally:
            ax._hold = washold

        return ret

.


2、gca 方法中 调用 gcf() 获取 figure 对象,并调用 figure 对象的 gca() 方法。

pyplot.py

    def gca(**kwargs):
        """
        Get the current :class:`~matplotlib.axes.Axes` instance on the
        current figure matching the given keyword args, or create one.

        Examples
        --------
        To get the current polar axes on the current figure::

            plt.gca(projection='polar')

        If the current axes doesn't exist, or isn't a polar one, the appropriate
        axes will be created and then returned.

        See Also
        --------
        matplotlib.figure.Figure.gca : The figure's gca method.
        """
        return gcf().gca(**kwargs)

pyplot.py

    def gcf():
    """Get a reference to the current figure."""
    figManager = _pylab_helpers.Gcf.get_active()
    if figManager is not None:
        return figManager.canvas.figure
    else:
        return figure()

.

3、figure 对象的 gca() 方法中,将返回 axes 对象。如果没有 axes 则会使用 self.add_subplot(1, 1, 1, **kwargs) 创建。

figure.py

    class Figure(Artist):

        """
        The Figure instance supports callbacks through a *callbacks*
        attribute which is a :class:`matplotlib.cbook.CallbackRegistry`
        instance.  The events you can connect to are 'dpi_changed', and
        the callback will be called with ``func(fig)`` where fig is the
        :class:`Figure` instance.

        *patch*
           The figure patch is drawn by a
           :class:`matplotlib.patches.Rectangle` instance

        *suppressComposite*
           For multiple figure images, the figure will make composite
           images depending on the renderer option_image_nocomposite
           function.  If suppressComposite is True|False, this will
           override the renderer.
        """

        ......
        ......
        ......

        @docstring.dedent_interpd
        def gca(self, **kwargs):
            """
            Get the current axes, creating one if necessary

            The following kwargs are supported for ensuring the returned axes
            adheres to the given projection etc., and for axes creation if
            the active axes does not exist:

            %(Axes)s

            """
            ckey, cax = self._axstack.current_key_axes()
            # if there exists an axes on the stack see if it maches
            # the desired axes configuration
            if cax is not None:

                # if no kwargs are given just return the current axes
                # this is a convenience for gca() on axes such as polar etc.
                if not kwargs:
                    return cax

                # if the user has specified particular projection detail
                # then build up a key which can represent this
                else:
                    # we don't want to modify the original kwargs
                    # so take a copy so that we can do what we like to it
                    kwargs_copy = kwargs.copy()
                    projection_class, _, key = process_projection_requirements(
                        self, **kwargs_copy)

                    # let the returned axes have any gridspec by removing it from
                    # the key
                    ckey = ckey[1:]
                    key = key[1:]

                    # if the cax matches this key then return the axes, otherwise
                    # continue and a new axes will be created
                    if key == ckey and isinstance(cax, projection_class):
                        return cax
                    else:
                        warnings.warn('Requested projection is different from '
                                      'current axis projection, creating new axis '
                                      'with requested projection.', stacklevel=2)

            # no axes found, so create one which spans the figure
            return self.add_subplot(1, 1, 1, **kwargs)

.

 

plt.show

源码 pyplot.py

def show(*args, **kw):
        """
        Display a figure.
        When running in ipython with its pylab mode, display all
        figures and return to the ipython prompt.

        In non-interactive mode, display all figures and block until
        the figures have been closed; in interactive mode it has no
        effect unless figures were created prior to a change from
        non-interactive to interactive mode (not recommended).  In
        that case it displays the figures but does not block.

        A single experimental keyword argument, *block*, may be
        set to True or False to override the blocking behavior
        described above.
        """
        global _show
        return _show(*args, **kw)

源码 pyplot.py

    _show = pylab_setup()

源码 backends/__init__.py

    def pylab_setup(name=None):
        '''return new_figure_manager, draw_if_interactive and show for pyplot

        This provides the backend-specific functions that are used by
        pyplot to abstract away the difference between interactive backends.

        Parameters
        ----------
        name : str, optional
            The name of the backend to use.  If `None`, falls back to
            ``matplotlib.get_backend()`` (which return ``rcParams['backend']``)

        Returns
        -------
        backend_mod : module
            The module which contains the backend of choice

        new_figure_manager : function
            Create a new figure manager (roughly maps to GUI window)

        draw_if_interactive : function
            Redraw the current figure if pyplot is interactive

        show : function
            Show (and possibly block) any unshown figures.

        '''

        ......
        ......
        ......

        return backend_mod, new_figure_manager, draw_if_interactive, show

.

 

plt.savefig

保存当前 figure 为图片。

官网 matplotlib.pyplot.savefig

savefig(fname, dpi=None, facecolor='w', edgecolor='w',
        orientation='portrait', papertype=None, format=None,
        transparent=False, bbox_inches=None, pad_inches=0.1,
        frameon=None)

参数:

fname : str 或者 file 对象,如果是 str 格式,文件的输出格式是根据 str 中的后缀决定的。如果字符串中没有后缀指定文件格式,则由 rc 参数 savefig.format 决定。

format : str,文件格式,一般支持 png、pdf、ps、eps 和 svg。

 

示例:

#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
"""
@author: tz_zs
"""

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(1, 100, 100)
y1 = np.random.randint(20, 60, size=100)
y2 = np.random.randint(30, 70, size=100)
y3 = np.random.randint(50, 90, size=100)

fig = plt.figure(num="111", figsize=(6, 4), facecolor="pink", edgecolor="green")
plt.plot(x, y1, c="red", label="y1_low")
plt.plot(x, y2, c="blue", label="y2_middle")
plt.plot(x, y3, c="yellow", label="y3_high")
plt.legend(loc="best")
# plt.show()
re = plt.savefig("a")
print(re)
"""
None
"""

.

matplotlib 之 pyplot 中常用方法的源码调用过程(plt.plot、plt.scatter、plt.hist、plt.bar、plt.show、plt.savefig)

 

源码调用过程:

获取当前 figure 的引用,然后调用 figure 对象的 savefig() 方法。

源码 pyplot.py

    def gcf():
    """Get a reference to the current figure."""
    figManager = _pylab_helpers.Gcf.get_active()
    if figManager is not None:
        return figManager.canvas.figure
    else:
        return figure()

    ......
    ......
    ......

    @docstring.copy_dedent(Figure.savefig)
    def savefig(*args, **kwargs):
        fig = gcf()
        res = fig.savefig(*args, **kwargs)
        fig.canvas.draw_idle()   # need this if 'transparent=True' to reset colors
        return res
    ......
    ......
    ......

figure.py

    class Figure(Artist):

        """
        The Figure instance supports callbacks through a *callbacks*
        attribute which is a :class:`matplotlib.cbook.CallbackRegistry`
        instance.  The events you can connect to are 'dpi_changed', and
        the callback will be called with ``func(fig)`` where fig is the
        :class:`Figure` instance.

        *patch*
           The figure patch is drawn by a
           :class:`matplotlib.patches.Rectangle` instance

        *suppressComposite*
           For multiple figure images, the figure will make composite
           images depending on the renderer option_image_nocomposite
           function.  If suppressComposite is True|False, this will
           override the renderer.
        """

        ......
        ......
        ......

        def savefig(self, fname, **kwargs):
            """
            Save the current figure.
            """
            ......
            ......
            ......
        ......
        ......
        ......

 

 

.

end

 

相关标签: pyplot