Python数据可视化Matplotlib学习

Matplotlib 是 Python 中最基本的可视化工具。类比一下人类和 Matplotlib 画图过程,人类画图需要三个步骤:

  1. 找画板
  2. 用调色板
  3. 画画

Matplotlib 模拟了类似过程,也分三步

  1. FigureCanvas
  2. Renderer
  3. Artist

在这里插入图片描述

上面是 Matplotlib 里的三层 API:

  • FigureCanvas 帮你确定画图的地方
  • Renderer 帮你把想画的东西展示在屏幕上
  • Artist 帮你用 Renderer 在 Canvas 上画图

一般用户只需用 Artist 就能自由的在电脑上画图了。

import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline 

注:%matplotlib inline 就是在 Jupyter notebook 里面内嵌画图的

# 可以将自己喜欢的颜色代码定义出来,然后再使用。
r_hex = '#dc2624'     # red,       RGB = 220,38,36
dt_hex = '#2b4750'    # dark teal, RGB = 43,71,80
tl_hex = '#45a0a2'    # teal,      RGB = 69,160,162
r1_hex = '#e87a59'    # red,       RGB = 232,122,89
tl1_hex = '#7dcaa9'   # teal,      RGB = 125,202,169
g_hex = '#649E7D'     # green,     RGB = 100,158,125
o_hex = '#dc8018'     # orange,    RGB = 220,128,24
tn_hex = '#C89F91'    # tan,       RGB = 200,159,145
g50_hex = '#6c6d6c'   # grey-50,   RGB = 108,109,108
bg_hex = '#4f6268'    # blue grey, RGB = 79,98,104
g25_hex = '#c7cccf'   # grey-25,   RGB = 199,204,207

在这里插入图片描述

1 Matplotlib基础介绍

1.1 概览

Matplotlib 包含两类元素:

  • 基础 (primitives) 类:线 (line), 点 (marker), 文字 (text), 图例 (legend), 网格 (grid), 标题 (title), 图片 (image) 等。
  • 容器 (containers) 类:图 (figure), 坐标系 (axes), 坐标轴 (axis) 和刻度 (tick)

基础类元素是我们想画出的标准对象,而容器类元素是基础类元素的寄居处,它们也有层级结构。

    图 → 坐标系 → 坐标轴 → 刻度

在这里插入图片描述

由上图看出:

  • 包含着坐标系 (多个)
  • 坐标系坐标轴 组成 (横轴 xAxis 和纵轴 yAxis)
  • 坐标轴 上面有刻度 (主刻度 MajorTicks 和副刻度 MinorTicks)

Python里面“万物皆对象”,坐标系、坐标轴和刻度都是对象。

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plt.show()

xax = ax.xaxis
yax = ax.yaxis

print( 'fig.axes:', fig.axes, '\n')
print( 'ax.xaxis:', xax )
print( 'ax.yaxis:', yax, '\n' )
print( 'ax.xaxis.majorTicks:', xax.majorTicks, '\n' )
print( 'ax.yaxis.majorTicks:', yax.majorTicks, '\n')
print( 'ax.xaxis.minorTicks:', xax.minorTicks )
print( 'ax.yaxis.minorTicks:', yax.minorTicks )

在这里插入图片描述

fig.axes: [<AxesSubplot:>] 

ax.xaxis: XAxis(54.0,36.0)
ax.yaxis: YAxis(54.0,36.0) 

ax.xaxis.majorTicks: [<matplotlib.axis.XTick object at 0x00000214C05AC240>, <matplotlib.axis.XTick object at 0x00000214C0599DA0>, <matplotlib.axis.XTick object at 0x00000214C05D6358>, <matplotlib.axis.XTick object at 0x00000214C05D6780>, <matplotlib.axis.XTick object at 0x00000214C05D6C18>, <matplotlib.axis.XTick object at 0x00000214C05D6E10>] 

ax.yaxis.majorTicks: [<matplotlib.axis.YTick object at 0x00000214C05ACA58>, <matplotlib.axis.YTick object at 0x00000214C05AC668>, <matplotlib.axis.YTick object at 0x00000214C05E8358>, <matplotlib.axis.YTick object at 0x00000214C05E8780>, <matplotlib.axis.YTick object at 0x00000214C05E8C18>, <matplotlib.axis.YTick object at 0x00000214C05F00F0>] 

ax.xaxis.minorTicks: [<matplotlib.axis.XTick object at 0x00000214C05B7390>]
ax.yaxis.minorTicks: [<matplotlib.axis.YTick object at 0x00000214C05CA390>]

坐标系和坐标轴指向同一个图 (侧面验证了图、坐标系和坐标轴的层级性)。

print( 'axes.figure:', ax.figure )
print( 'xaxis.figure:', xax.figure )
print( 'yaxis.figure:', yax.figure )
axes.figure: Figure(432x288)
xaxis.figure: Figure(432x288)
yaxis.figure: Figure(432x288)

创造完以上四个容器元素后,我们可在上面添加各种基础元素,比如:

  • 在坐标轴和刻度上添加标签
  • 在坐标系中添加线、点、网格、图例和文字
  • 在图中添加图例

1.2 图

# 图是整个层级的顶部,在图中可以添加基本元素「文字」。
plt.figure()
plt.text( 0.5, 0.5, 'Figure', ha='center', 
          va='center', size=20, alpha=.5 )
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

用 plt.text() 函数,其参数解释如下:

  • 第一、二个参数是指文字所处位置的横轴和纵轴坐标
  • 第三个参数字符是指要显示的内容
  • ha, va 是横向和纵向位置,指文字与其所处“坐标”之间是左对齐、右对齐或居中对齐
  • size 设置字体大小
  • alpha 设置字体透明度 (0.5 是半透明)
# 在图中可以添加基本元素「折线」。
plt.figure()
plt.plot( [0,1],[0,1] )
plt.show()

在这里插入图片描述

当我们每次说画东西,看起来是在图 (Figure) 里面进行的,实际上是在坐标系 (Axes) 里面进行的。一幅图中可以有多个坐标系,因此在坐标系里画东西更方便 (有些设置使用起来也更灵活)。

1.3 坐标系与子图

一幅图 (Figure) 中可以有多个坐标系 (Axes),那不是说一幅图中有多幅子图 (Subplot),因此坐标系和子图是不是同样的概念?
在绝大多数情况下是的,两者有一点细微差别:

  • 子图在母图中的网格结构一定是规则的
  • 坐标系在母图中的网格结构可以是不规则的

子图

把图想成矩阵,那么子图就是矩阵中的元素,因此可像定义矩阵那样定义子图 - (行数、列数、第几个子图)。

subplot(rows, columns, i-th plots)
plt.subplot(2, 1, 1)
plt.xticks([])
plt.yticks([])
plt.text(0.5, 0.5, 'subplot(2, 1, 1)', ha='center', va='center', size=20, alpha=0.5)

plt.subplot(2, 1, 2)
plt.xticks([])
plt.yticks([])
plt.text(0.5, 0.5, 'subplot(2, 1, 2)', ha='center', va='center', size=20, alpha=0.5)
Text(0.5, 0.5, 'subplot(2, 1, 2)')

在这里插入图片描述

这两个子图类似于一个列向量

  • subplot(2,1,1) 是第一幅
  • subplot(2,1,2) 是第二幅
plt.subplot(1, 2, 1)
plt.xticks([])
plt.yticks([])
plt.text(0.5, 0.5, 'subplot(1, 2, 1)', ha='center', va='center', size=20, alpha=0.5)

plt.subplot(1, 2, 2)
plt.xticks([])
plt.yticks([])
plt.text(0.5, 0.5, 'subplot(1, 2, 2)', ha='center', va='center', size=20, alpha=0.5)

Text(0.5, 0.5, 'subplot(1, 2, 2)')

在这里插入图片描述

这两个子图类似于一个行向量

  • subplot(1,2,1) 是第一幅
  • subplot(1,2,2) 是第二幅
fig, axes = plt.subplots(nrows=2, ncols=2)

for i, ax in enumerate(axes.flat):
    ax.set(xticks=[], yticks=[])
    s = 'subplot(2, 2,' + str(i) + ')'
    ax.text(0.5, 0.5, s, ha='center', va='center', size=20, alpha=0.5)
plt.show()

在这里插入图片描述

这次我们用过坐标系来生成子图 (子图是坐标系的特例嘛),第 1 行

fig, axes = plt.subplots(nrows=2, ncols=2)

得到的 axes 是一个 2×2 的对象。在第 3 行的 for 循环中用 axes.flat 将其打平,然后在每个 ax 上生成子图。

坐标系

坐标系比子图更通用,有两种生成方式

  • 用 gridspec 包加上 subplot()
  • 用 plt.axes()
不规则网格
import matplotlib.gridspec as gridspec
G = gridspec.GridSpec(3, 3) # 将整幅图分成 3×3 份赋值给 G

ax1 = plt.subplot(G[0, :])
plt.xticks([]), plt.yticks([])
plt.text(0.5, 0.5, 'Axes 1', ha='center', va='center', size=20, alpha=0.5)

ax2 = plt.subplot(G[1,:-1])
plt.xticks([]), plt.yticks([])
plt.text(0.5, 0.5, 'Axes 2', ha='center', va='center', size=20, alpha=0.5)

ax3 = plt.subplot(G[1:,-1])
plt.xticks([]), plt.yticks([])
plt.text(0.5, 0.5, 'Axes 3', ha='center', va='center', size=20, alpha=0.5)

ax4 = plt.subplot(G[-1, 0])
plt.xticks([]), plt.yticks([])
plt.text(0.5, 0.5, 'Axes 4', ha='center', va='center', size=20, alpha=0.5)

ax5 = plt.subplot(G[-1,1])
plt.xticks([]), plt.yticks([])
plt.text(0.5, 0.5, 'Axes 5', ha='center', va='center', size=20, alpha=0.5)

plt.show()

在这里插入图片描述

plt.subplot(G[]) 函数生成五个坐标系。G[] 里面的切片和 Numpy 数组用法一样:

  • G[0, :] = 图的第一行 (Axes 1)
  • G[1, :-1] = 图的第二行,第一二列 (Axes 2)
  • G[1:, -1] = 图的第二三行,第三列 (Axes 3)
  • G[-1, 0] = 图的第三行,第一列 (Axes 4)
  • G[-1, 1] = 图的第三行,第二列 (Axes 5)
大图套小图
plt.axes([0.1, 0.1, 0.8, 0.8])
plt.xticks([]), plt.yticks([])
plt.text(0.6, 0.6, 'axes([0.1,0.1,0.8,0.8])', ha='center', va='center', size=20, alpha=0.5)

plt.axes([0.2, 0.2, 0.3, 0.3])
plt.xticks([]), plt.yticks([])
plt.text(0.5, 0.5, 'axes([0.2,0.2,0.3,0.3])', ha='center', va='center', size=10, alpha=0.5)

plt.show()

在这里插入图片描述

plt.axes([l,b,w,h]) 函数,其中 [l, b, w, h] 可以定义坐标系

  • l 代表坐标系左边到 Figure 左边的水平距离
  • b 代表坐标系底边到 Figure 底边的垂直距离
  • w 代表坐标系的宽度
  • h 代表坐标系的高度

如果 l, b, w, h 都小于 1,那它们是标准化 (normalized) 后的距离。比如 Figure 底边长度为 10, 坐标系底边到它的垂直距离是 2,那么 b = 2/10 = 0.2。

生成坐标系的2种方式

# 1.同时生成图和坐标系
fig, ax = plt.subplots()
plt.xticks([]), plt.yticks([])
s = 'Style 1\n\nfig,ax=plt.subplots()\nax,plot()'
ax.text(0.5, 0.5, s, ha='center', va='center',size=20,alpha=0.5)
plt.show()

在这里插入图片描述

# 2.先生成图,再添加坐标系
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.set(xticks=[],yticks=[])
s = 'Style 2\n\nfig=plt.figure()\nax=fig.add_subplot()\nax.plot()'
ax.text(0.5,0.5,s,ha='center',va='center',size=20,alpha=0.5)
plt.show()

在这里插入图片描述

1.4 坐标轴

一个坐标系 (Axes),通常是二维,有两条坐标轴 (Axis):

  • 横轴:XAxis
  • 纵轴:YAxis

每个坐标轴都包含两个元素

  • 容器类元素「刻度」,该对象里还包含刻度本身和刻度标签
  • 基础类元素「标签」,该对象包含的是坐标轴标签

「刻度」和「标签」都是对象。

r_hex
'#dc2624'
fig, ax = plt.subplots()
ax.set_xlabel('Label on x-axis')
ax.set_ylabel('Label on y-axis')

for label in ax.xaxis.get_ticklabels():
    # label is a text instance
    # 标签是一个文本对象
    label.set_color(dt_hex)
    label.set_rotation(45)
    label.set_fontsize(20)

for line in ax.yaxis.get_ticklines():
    # line is a line2D instance
    # 刻度是一个二维线段对象

    line.set_markersize(20)
    line.set_markeredgewidth(3)

plt.show()

在这里插入图片描述

第 2 和 3 行打印出 x 轴和 y 轴的标签。

第 5 到 9 行处理「刻度」对象里的刻度标签,将它颜色设定为深青色,字体大小为 20,旋转度 45 度。

第 11 到 15 行处理「标签」对象的刻度本身 (即一条短线),标记长度和宽度为 20 和 3。

1.5 刻度

刻度 (Tick) 的核心内容就是

  • 一条短线 (刻度本身)
  • 一串字符 (刻度标签)

首先定义一个 setup(ax) 函数,主要功能有

  • 去除左纵轴 (y 轴)、右纵轴和上横轴
  • 去除 y 轴上的刻度
  • 将 x 轴上的刻度位置定在轴底
  • 设置主刻度和副刻度的长度和宽度
  • 设置 x 轴和 y 轴的边界
  • 将图中 patch 设成完全透明

将上面效果全部合并,这个 setup(ax) 就是把坐标系里所有元素都去掉,只留 x 轴来添加各种刻度。

import matplotlib.ticker as ticker
def setup(ax):
    ax.spines['right'].set_color('none') # 去除左纵轴 (y 轴)
    ax.spines['left'].set_color('none') # 去除右纵轴
    ax.spines['top'].set_color('none') # 去除上横轴
    ax.yaxis.set_major_locator(ticker.NullLocator()) # 去除y轴上的刻度
    ax.xaxis.set_ticks_position('bottom') # 把x轴上的刻度位置定在轴底
    
    ax.tick
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值