matplotlib封装探索

本文参考这里,转载请注明出处!绘图:matplotlib核心剖析

matplotlib是基于Python的开源项目,旨在为Python提供一个数据绘图包。在建模过程中数据分布,图表的分析非常重要。

Matplotlib使用numpy数组运算,并调用一系列其他的Python库来实现硬件交互。matplotlib的核心是一套由对象构成的绘图API。

matplotlib项目由John D. Hunter发起,他于2012年由于癌症去世,默哀。

函数式构图

matplotlib受MATLAB启发构建,注意,MATLIB是面向过程的,matplotlib为了方便用户过度,有一套完全仿照MATLIB的函数形式的用户结构,在matplotlib.pyplot中,就是我们经常在比赛中使用的如下引入方式import matplotlib.pyplot as plt

# hello world
import matplotlib.pyplot as plt
plt.plot([0,1], [0,1])
plt.title("plot hello world")
plt.xlabel("x value")
plt.ylabel("y value")
plt.savefig("demo.png")

demo

这种函数式调用非常方便,但是我们知道python中一切皆对象,函数式编程是通过封装对象来实现的,将构建对象的过程中封装在函数中 。matplotlib也是如此,所以本质上还是通过构建对象来构建图像。常用的绘图函数plot,scatter,pie,bar,contour,imshow

面向对象的编程

函数式编程对用户很友好,也很便利,但是也有缺点:

  • 增加了一层调用,降低了效率
  • 隶属关系被掩盖,整个matplotlib包由一系列有组织有隶属关系的对象构成,函数式编程掩盖了这种关系。
  • 细节被掩盖,pyplot不能完全覆盖对象体系的所有功能
  • 每件事都可以有至少有两种方式完成,用户容易混淆。

对于开发者或者想更加熟练使用matplotlib还是了解对象才好。

# 用面向对象的方法来实现以上程序
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

fig    = Figure()
canvas = FigureCanvas(fig)
ax     = fig.add_axes([0.1, 0.1, 0.8, 0.8])

line,  = ax.plot([0,1], [0,1])
ax.set_title("a straight line (OO)")
ax.set_xlabel("x value")
ax.set_ylabel("y value")

canvas.print_figure('demo.png')

demo_oo

理解对象

在matplotlib中,整个图像为一个Figure对象,在Figure对象中可以包含一个或者多个Axes对象,每个Axes对象都有一个拥有自己坐标系统的绘图区域。逻辑关系如下:

这里写图片描述

看上边的直线图,整个图像就是一个Figure对象,我们的绘图只有一个坐标系区域,此外还有以下对象。

这里写图片描述

其中title为标题,axis为坐标轴,label为坐标轴标注,tick为刻度线,tick label为刻度注释,各个对象的关系如下所示。

这里写图片描述

data是数据绘图的关键部分,但是必须和xaxis,yaxis,title一起才有意义,才能构成一个绘图区域axes,title, tick label和label都是文本(Text),而tick是由短线(Line 2D)和tick label构成,xaxis由坐标轴的线和tick以及label构成,ax由xaxis, yaxis, title, data构成,ax自身又构成了fig的一部分。上面的每个对象,无论是Line2D, Text还是fig,它们都来自于一个叫做Artist的基类。

OO绘图源程序还有一个canvas对象,它代表了真正进行绘图的后端,Artist只是程序逻辑上的绘图,它必须连接后端绘图程序才能真正在绘图程序上绘制。可以将canvas理解为绘图的物理(硬件)实现。

坐标

三种坐标:

  • 显示坐标:计算机屏幕是以像素点构成,显示坐标就是以像素点为单位,最贴近硬件的坐标体系。缺点,不容易被纳入绘图逻辑,在不同的显示器上需要调整像素值才能保证图像不变形。
  • 图像坐标:将一张图的左下角视为原点,将图像的x方向和y方向总长度都看做1,x方向的0.2就是指20%的图像在x方向的总长,y方向0.8的长度指80%的y方向总长。(0.5, 0.5)是图像的中点,(1, 1)指图像的右上角。在上边的OO绘图代码中,ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]),前两个参数为axes的左下角在fig上的位置,后两个原始是axes在fig的图像坐标上x和y方向的长度,fig的图像坐标为图像坐标(figure坐标)。类似地,每个axes有属于自己的图像坐标,称为数据坐标(axes坐标)
  • 数据坐标:实际绘图使用,绘制具体数据。

如果是具体数据,那么数据坐标系符合我们需求。如果是标题这样的附加信息,axes坐标符合我们需求。如果是整个图像的注解,Figure坐标系更符合需求。每一个Aritist对象都有一个transform属性,如果为显示坐标,transform为None。

以更大自由度(更底层)来绘制图形可以参见这里

猜你喜欢

转载自blog.csdn.net/wj1066/article/details/78896019
今日推荐