一文了解python作图(matplotlib.pyplot)

参考视频:为什么用 Matplotlib

视频总时长两个多小时,可以整体看一遍,然后看这个就会很清楚

1. 基本用法

1.1 基础作图

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1, 1, 50)
y = x * x + 1
plt.plot(x, y)
plt.show()

image-20230112115955135

1.2 figure图像

在不同的figure中展示不同的图片,在每次绘图前指定plt.figure()即可绘制到不同figure中,其中可以指定figure的序号

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1, 1, 50)
y1 = x * x + 1
y2 = 2 * x

plt.figure(num=1)
plt.plot(x, y1)

plt.figure(num=2, figsize=(8, 5))
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth='1.0', linestyle='--')
plt.show()

figure1:

image-20230112120932920

figure2:
image-20230112120941486

1.3 设置坐标轴

1.3.1 基本设置

  • plt.xlim(xleft, xright):设置x轴显示范围
  • plt.ylim(ylow, yhigh):设置y轴的显示范围
  • plt.xlabel(description):设置x轴描述
  • plt.ylabel(description):设置y轴描述
  • plt.xticks([1,2,3,4,5]):设置x轴标签
  • plt.yticks([1,2,3,4,5]):设置y轴标签
  • plt.yticks([1,2,3], ['one','two','three]):设置对应标签位置文字
  • plt.xlabel(r'$axis x description \alpha$'):使用latex公式
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = x * x + 1
y2 = 2 * x

plt.figure(num=2, figsize=(8, 5))
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth='1.0', linestyle='--')

# 设置x,y轴的显示范围
plt.xlim(-1, 2)
plt.ylim(-2, 3)

# 设置x,y轴的坐标轴描述
plt.xlabel('axis x description')
plt.ylabel('axis y description')

# 设置分度值
new_ticks = np.linspace(-1, 2, 5)
plt.xticks(new_ticks)

# 设置为中文
plt.yticks([-2, -1.5, 0, 1, 3],
           ['really bad', 'bad', 'normal', 'good', 'really god'])

plt.show()

image-20230112122012788

1.3.2 使用Latex公式

其中文字部分也可以使用latex公式进行描述,例如设置某个label为 g o o d   β good\ \beta good β

# 设置为中文
plt.yticks([-2, -1.5, 0, 1, 3],
           ['really bad', 'bad', 'normal', r'$good\ \beta$', 'really god'])

image-20230112122137145

1.3.3 设置坐标轴位置

首先去掉右边和上边两个边框,然后设置x轴为下边框,y轴为上边框,最后设置边框位置即可

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = x * x + 1
y2 = 2 * x

plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth='1.0', linestyle='--')

# 设置x,y轴的显示范围
plt.xlim(-1, 2)
plt.ylim((-2, 3))

# 设置x,y轴的坐标轴描述
plt.xlabel(r'$axis x description$', loc="right")
plt.ylabel('axis y description', loc='top')

# 设置分度值
new_ticks = np.linspace(-1, 2, 5)
plt.xticks(new_ticks)

# 设置为中文
plt.yticks([-2, -1.5, 0, 1, 3],
           ['really bad', 'bad', 'normal', r'$good\ \beta$', 'really god'])

# gca: get current axis
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))

plt.show()

image-20230112133528536

1.4 legend图例

1.4.1 基础使用

通过给每一个plot出来的图像添加label属性,然后调用plt.legend()即可显示图例

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = x * x + 1
y2 = 2 * x

# 设置x,y轴的显示范围
plt.xlim(-1, 2)
plt.ylim((-2, 3))

# 设置x,y轴的坐标轴描述
plt.xlabel(r'$axis x description$')
plt.ylabel('axis y description')

# 设置分度值
new_ticks = np.linspace(-1, 2, 5)
plt.xticks(new_ticks)

# 设置为中文
plt.yticks([-2, -1.5, 0, 1, 3],
           ['really bad', 'bad', 'normal', r'$good\ \beta$', 'really god'])

plt.plot(x, y2, label='up')
plt.plot(x, y1, color='red', linewidth='1.0', linestyle='--', label='down')
plt.legend()

plt.show()

image-20230112133953566

1.4.2 设置图例位置

支持的位置属性:'best', 'upper right', 'upper left', 'lower left', 'lower right', 'right', 'center left', 'center right', 'lower center', 'upper center', 'center'

best是根据线的显示位置寻找最优的显示地方

通过调用plt.legend(loc='')指定loc属性即可

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = x * x + 1
y2 = 2 * x

# 设置x,y轴的显示范围
plt.xlim(-1, 2)
plt.ylim((-2, 3))

# 设置x,y轴的坐标轴描述
plt.xlabel(r'$axis x description$')
plt.ylabel('axis y description')

# 设置分度值
new_ticks = np.linspace(-1, 2, 5)
plt.xticks(new_ticks)

# 设置为中文
plt.yticks([-2, -1.5, 0, 1, 3],
           ['really bad', 'bad', 'normal', r'$good\ \beta$', 'really god'])

plt.plot(x, y2, label='up')
plt.plot(x, y1, color='red', linewidth='1.0', linestyle='--', label='down')
plt.legend(loc="upper right")

plt.show()

image-20230112134007231

1.4.3 指定显示某几条线并设置新名称

虽然绘制了两条线,但是通过handles属性可以指定绘制某几条线,同时也可以设置各线的先后位置,另外还可以通过labels指定新的图例名称

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = x * x + 1
y2 = 2 * x

# 设置x,y轴的显示范围
plt.xlim(-1, 2)
plt.ylim((-2, 3))

# 设置x,y轴的坐标轴描述
plt.xlabel(r'$axis x description$')
plt.ylabel('axis y description')

# 设置分度值
new_ticks = np.linspace(-1, 2, 5)
plt.xticks(new_ticks)

# 设置为中文
plt.yticks([-2, -1.5, 0, 1, 3],
           ['really bad', 'bad', 'normal', r'$good\ \beta$', 'really god'])

l1, = plt.plot(x, y2, label='up')
l2, = plt.plot(x, y1, color='red', linewidth='1.0', linestyle='--', label='down')
plt.legend(handles=[l1], labels=['aaa'], loc="upper right")

plt.show()

image-20230112134115995

1.5 annotation 注解

通过plt.annotation()plt.text()为图象添加注解

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y1 = 2 * x + 1

plt.figure(figsize=(8, 5))
plt.plot(x, y1)

# gca: get current axis
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))

x0 = 1
y0 = 2 * x0 + 1
plt.scatter(x0, y0, s=50, color='b')
plt.plot([x0, x0], [0, y0], 'k--', linewidth=2)

plt.annotate(r"$2x+1=%s$" % y0, xy=(x0, y0), xycoords='data', xytext=(+30, -30), textcoords='offset points',fontsize=16, arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=.2'))

plt.text(-3, 3, r"$This\ is\ annotation.\ \mu\ \sigma_i $", fontdict={
    
    'size': 16, "color": 'r'})
plt.show()

image-20230112135641177

1.6 设置tick可见度

有时候线会把标签压住,此时可以通过设置标签的zorder属性来制定覆盖顺序

zorder用来控制绘图的顺序,也就是所谓的叠加样式。zorder越大,相当于画上去的越晚,也就在上面了。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 50)
y2 = 0.1 * x

plt.plot(x, y2, linewidth=10, zorder=1)
plt.ylim(-2, 2)
# gca: get current axis
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 0))

for label in ax.get_xticklabels() + ax.get_yticklabels():
    label.set_zorder(2)
    label.set_fontsize(12)
    label.set_bbox(dict(
        facecolor='white',
        edgecolor='None',
        alpha=0.7
    ))

plt.show()

2 数据呈现

2.1 散点图

通过plt.scatter()生成散点图

import matplotlib.pyplot as plt
import numpy as np

n = 1024

X = np.random.normal(0, 1, n)
Y = np.random.normal(0, 1, n)
T = np.arctan2(Y, X)

plt.scatter(X, Y, s=75, c=T, alpha=.5)

plt.xlim(-1.5, 1.5)
plt.ylim(-1.5, 1.5)

plt.xticks([])
plt.yticks([])
plt.show()

image-20230112144357743

生成一条斜线散点图

import matplotlib.pyplot as plt
import numpy as np

plt.scatter(np.arange(5), np.arange(5))

plt.show()

image-20230112144522776

2.2 条形图

使用plt.bar()绘制条形图

import matplotlib.pyplot as plt
import numpy as np

n = 12
X = np.arange(n)
Y1 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)
Y2 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)

plt.bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
plt.bar(X, -Y2, facecolor='#ff9999', edgecolor='white')

for x, y in zip(X, Y1):
    # ha: horizontal alignment
    plt.text(x, y + 0.05, '%.2f' % y, ha='center', va='bottom')

for x, y in zip(X, Y2):
    # ha: horizontal alignment
    plt.text(x, -y - 0.05, '%.2f' % y, ha='center', va='top')

plt.xlim(-0.5, n)
plt.xticks([])
plt.ylim(-1.25, 1.25)
plt.yticks([])

plt.show()

image-20230112145601327

2.3 等高线图

  • 使用plt.meshgrid()生成框格
  • 使用plt.contourf()生成等高线填充图
  • 使用plt.contour()生成等高线
import matplotlib.pyplot as plt
import numpy as np


def f(x, y):
    # 高度计算公式
    return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)


n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)

# 生成框格
X, Y = np.meshgrid(x, y)

# 设置等高线图
plt.contourf(X, Y, f(X, Y), 8, alpha=0.75, cmap=plt.cm.hot)

# 设置等高线
C = plt.contour(X, Y, f(X, Y), 8, colors='black')

# 添加高度标签
plt.clabel(C, inline=True, fontsize=10)
plt.xticks([])
plt.yticks([])
plt.show()

image-20230112150337064

2.4 使用图片

import matplotlib.pyplot as plt
import numpy as np

img = np.random.uniform(0, 1000, 100).reshape((10, 10))

plt.imshow(img, interpolation='nearest', origin='upper')
plt.colorbar()

plt.xticks([])
plt.yticks([])
plt.show()

image-20230112153409740

2.5 3D数据

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 生成3D figure
fig = plt.figure()
ax = Axes3D(fig, auto_add_to_figure=False)
fig.add_axes(ax)

# X, Y value
X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X ** 2 + Y ** 2)

Z = np.sin(R)

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'), edgecolor='k')
ax.contourf(X, Y, Z, zdir='z', offset=-2, cmap='rainbow')

ax.set_zlim(-2, 2)
plt.show()

image-20230112154447952

3. Subplot多合一显示

3.1 plt.subplot

使用plt.subplot(rownum, columnnum, index)说明新图纸是几行几列的

import matplotlib.pyplot as plt

plt.figure()
plt.subplot(2, 2, 1)
plt.plot([0, 1], [0, 1])

plt.subplot(2, 2, 2)
plt.plot([0, 1], [0, 1])

plt.subplot(2, 1, 2)
plt.plot([0, 1], [0, 1])

plt.show()

image-20230112154912308

3.2 plt.subplot2grid

使用plt.subplot2grid(总格数, 起始格数, rowspan, colspan)来绘制

import matplotlib.pyplot as plt

plt.figure()
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3, rowspan=1)
ax1.plot([1, 2], [1, 2])
# 设置某属性的时候需要在前面加set_
ax1.set_title("ax1 title")

ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3, 3), (2, 0))
ax5 = plt.subplot2grid((3, 3), (2, 1))

plt.tight_layout()
plt.show()

image-20230112160001950

3.3 gridspec.GridSpec

首先使用gridspec.GridSpec(rownum, colnum)声明将figure分割成几块,然后在绘图时使用切片声明使用哪几块即可

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

plt.figure()
gs = gridspec.GridSpec(3, 3)
ax1 = plt.subplot(gs[0, :])
ax2 = plt.subplot(gs[1, :2])
ax3 = plt.subplot(gs[1:, 2])
ax4 = plt.subplot(gs[2, 0])
ax5 = plt.subplot(gs[2, 1])

plt.tight_layout()
plt.show()

image-20230112160140602

3.4 plt.subplots

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

f, ((ax11, ax12), (ax21, ax22)) = plt.subplots(2, 2, sharex=True, sharey=True)
ax11.plot([1, 2], [1, 2])

plt.tight_layout()
plt.show()

image-20230112160457523

4. 其他

4.1 图中图

通过指定在整个figure中的位置和大小来完成图中图的效果

  • 方法一:通过fig.add_axes([left, bottom, width, height])来生成新的axes绘制
  • 方法二:通过plt.axes([left, bottom, width, height])直接声明接下来要绘制的图形
import matplotlib.pyplot as plt

fig = plt.figure()
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 3, 4, 2, 5, 8, 6]

# 大图
left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
ax1 = fig.add_axes([left, bottom, width, height])
ax1.plot(x, y)
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_title('title')

# 小图
left, bottom, width, height = 0.2, 0.6, 0.25, 0.25
ax1 = fig.add_axes([left, bottom, width, height])
ax1.plot(y, x, 'b')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_title('inside 1')

# 另一种方法
plt.axes([0.6, 0.2, 0.25, 0.25])
plt.plot(y[::-1], x, 'g')
plt.xlabel('x')
plt.ylabel('y')
plt.title('inside 2')

plt.show()

image-20230112161104789

4.2 次坐标轴

在同一个图中两边显示不同的坐标轴对应不同的数据

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 0.1)
y1 = 0.05 * x ** 2
y2 = -1 * y1

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

ax1.plot(x, y1, 'g-')
ax2.plot(x, y2, 'b--')

ax1.set_xlabel('X data')
ax1.set_ylabel('Y1', color='g')
ax2.set_ylabel('Y2', color='g')

plt.show()

image-20230112161531393

4.3 动画 animation

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots()

x = np.arange(0, 2 * np.pi, 0.01)
line, = ax.plot(x, np.sin(x))


def animate(i):
    line.set_ydata(np.sin(x + i / 10))
    return line,


def init():
    line.set_ydata(np.sin(x))
    return line,


ani = animation.FuncAnimation(fig=fig, func=animate, frames=100, init_func=init, interval=20, blit=True)

plt.show()

image-20230112162156500

image-20230112162205364

猜你喜欢

转载自blog.csdn.net/qq_46311811/article/details/128662105