Matplotlib从入门到精通

Matplotlib 是 Python 生态中最基础、最强大的数据可视化库 ,被誉为 Python 可视化的"祖父 "和"瑞士军刀 "。它的核心价值在于提供了无与伦比的灵活性和控制力,允许你从零开始创建和定制几乎任何类型的静态、动画或交互式图表。

核心定位与特点

  • 定位 :Python 科学计算栈(NumPy, SciPy, Pandas)的基础绘图库。许多高级可视化库(如 Seaborn, pandas.plot)都构建在 Matplotlib 之上。

  • 核心特点

    1. 全面控制:你可以控制图表的每一个像素,从坐标轴刻度到图例样式,实现出版级精度的输出。

    2. 广泛的图表支持:支持折线图、散点图、柱状图、直方图、饼图、等高线图、3D图等数十种图表。

    3. 多输出格式:可将图表输出为 PNG, PDF, SVG, EPS 等多种图片或矢量格式。

    4. 跨平台交互:在 Jupyter Notebook、独立脚本、Web 应用服务器中均可使用。

一 画直线图

1.1 figure使用

复制代码
import numpy as np
import matplotlib.pyplot as plt

# 从-3到中取50个数
x = np.linspace(-3, 3, 50)
print(x)
y1 = 2*x+1
y2 = x**2
plt.figure()
plt.plot(x, y1)
plt.figure(num=3, figsize=(8, 5))   # figsize的设置长和宽
plt.plot(x, y2)
plt.plot(x, y1, color='red', linewidth=10.0, linestyle='--')   # linewidth 设置线的宽度, linesyyle设置线的形状
# savefig  保存图片
plt.savefig("./image_dir/xianxing.png")
plt.show()

1.2 设置坐标轴

复制代码
# 从-3到中取50个数
    x = np.linspace(-3, 3, 50)

    y1 = 2 * x + 1
    y2 = x ** 2
    plt.figure(num=3, figsize=(8, 5))  # figsize的设置长和宽
    plt.plot(x, y2)
    plt.plot(x, y1, color='red', linewidth=10.0, linestyle='--')
    plt.xlim((-1, 2))   # 设置x轴的范围
    plt.ylim((-2, 3))   # 设置y轴的范围
    plt.xlabel('I am x')  # 设置x轴的名称
    plt.ylabel('I am y')   # 设置y轴额名称
    new_ticks = np.linspace(-1, 2, 5)
    print(new_ticks)
    plt.xticks(new_ticks)   # 设置x轴的范围的刻度值
    # 设置y轴的范围的刻度值
    plt.yticks([-2, -1, 0, 1, 2, 3],
               [r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])
    plt.savefig('./image_dir/xlim.png')
    plt.show()
复制代码
# 从-3到中取50个数
    x = np.linspace(-3, 3, 50)

    y1 = 2 * x + 1
    y2 = x ** 2
    plt.figure(num=3, figsize=(8, 5))  # figsize的设置长和宽
    plt.plot(x, y2)
    plt.plot(x, y1, color='red', linewidth=10.0, linestyle='--')
    plt.xlim((-1, 2))   # 设置x轴的范围
    plt.ylim((-2, 3))   # 设置y轴的范围
    plt.xlabel('I am x')  # 设置x轴的名称
    plt.ylabel('I am y')   # 设置y轴额名称
    new_ticks = np.linspace(-1, 2, 5)
    print(new_ticks)
    plt.xticks(new_ticks)   # 设置x轴的范围的刻度值
    # 设置y轴的范围的刻度值
    plt.yticks([-2, -1, 0, 1, 2, 3],
               [r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])
    # gca = 'get current axis'
    ax = plt.gca()
    #  将轴的右边去掉
    ax.spines['right'].set_color('none')
    #  将轴的上边去掉
    ax.spines['top'].set_color('none')
    #  将下轴设置为x
    ax.xaxis.set_ticks_position('bottom')
    # 将左轴设置为y
    ax.yaxis.set_ticks_position('left')
    # 设置下轴的位置  set_position(outward, axes)
    ax.spines['bottom'].set_position(('data', 0))
    # 设置左轴位置
    ax.spines['left'].set_position(('data', '0'))
    plt.savefig('./image_dir/xlim2.png')
    plt.show()

1.3 legend 图例

复制代码
# 从-3到中取50个数
    x = np.linspace(-3, 3, 50)

    y1 = 2 * x + 1
    y2 = x ** 2
    plt.figure(num=3, figsize=(8, 5))  # figsize的设置长和宽

    plt.xlim((-1, 2))   # 设置x轴的范围
    plt.ylim((-2, 3))   # 设置y轴的范围
    plt.xlabel('I am x')  # 设置x轴的名称
    plt.ylabel('I am y')   # 设置y轴额名称
    new_ticks = np.linspace(-1, 2, 5)
    print(new_ticks)
    plt.xticks(new_ticks)   # 设置x轴的范围的刻度值
    # 设置y轴的范围的刻度值
    plt.yticks([-2, -1, 0, 1, 2, 3],
               [r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$really\ good$'])

    # plt.plot是有返回值的
    l1, =  plt.plot(x, y2, label='up')
    l2, = plt.plot(x, y1, color='red', linewidth=10.0, linestyle='--', label='down')
    # handles,   labels是设置名称, loc是设置位置
    plt.legend(handles=[l1, l2], labels=['aaa', 'bbb'], loc='best')
    plt.savefig('./image_dir/xlim3.png')
    plt.show()

1.4 annotation标注

复制代码
# 从-3到中取50个数
    x = np.linspace(-3, 3, 50)
    y1 = 2 * x + 1
    # y2 = x ** 2
    plt.figure(num=3, figsize=(8, 5))  # figsize的设置长和宽
    # plt.plot(x, y2)
    plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--')
    # gca = 'get current axis'
    ax = plt.gca()
    #  将轴的右边去掉
    ax.spines['right'].set_color('none')
    #  将轴的上边去掉
    ax.spines['top'].set_color('none')
    #  将下轴设置为x
    ax.xaxis.set_ticks_position('bottom')
    # 将左轴设置为y
    ax.yaxis.set_ticks_position('left')
    # 设置下轴的位置  set_position(outward, axes)
    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], [y0, 0], 'k--', lw=2.5)

    # method1   xycoords依赖的数据集
    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'))

    # method2
    plt.text(-3.7, 3, r'$ this is the some test mu sigma_i alpha_t$', fontdict={'size':16, 'color':'r'})
    plt.savefig('./image_dir/xlim4.png')
    plt.show()

1.5 tick能见度

复制代码
# 从-3到中取50个数
    x = np.linspace(-3, 3, 50)
    y1 = 0.1*x
    # y2 = x ** 2
    plt.figure(num=3, figsize=(8, 5))  # figsize的设置长和宽
    # plt.plot(x, y2)
    plt.plot(x, y1, linewidth=10)
    plt.ylim(-2, 2)
    # gca = 'get current axis'
    ax = plt.gca()
    #  将轴的右边去掉
    ax.spines['right'].set_color('none')
    #  将轴的上边去掉
    ax.spines['top'].set_color('none')
    #  将下轴设置为x
    ax.xaxis.set_ticks_position('bottom')
    # 将左轴设置为y
    ax.yaxis.set_ticks_position('left')
    # 设置下轴的位置  set_position(outward, axes)
    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_fontsize(12)
        label.set_bbox(dict(facecolor='blue', edgecolor='None', alpha=0.9))
    plt.savefig('./image_dir/xlim5.png')
    plt.show()

二 散点图

scatter函数原型:

其中散点的形状参数marker如下:

其中颜色参数c如下:

复制代码
    n = 1024
    # 均值是0, 方差是1, 取1024个数
    x = np.random.normal(0, 1, n)
    y = np.random.normal(0, 1, n)
    # 设置颜色值
    T = np.arctan2(y, x)
    bar = plt.scatter(x, y, s=10, c=T, alpha=0.5, cmap='hot')
    # plt.xticks(())
    # plt.yticks(())
    plt.colorbar(bar)
    plt.savefig('./image_dir/scatter.png')
    plt.show()

三 柱状图

复制代码
    n = 12
    x = np.arange(n)
    print(x)
    # np.random.uniform(0.5, 1.0, n)  去、取0.5 到 1 之间12个数
    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')
    plt.xticks(())
    plt.yticks(())
    for x, y, y2 in zip(x, y1, y2):
        # 给每根柱子加上标识
        plt.text(x, y+0.05, '%.2f'%y, ha='center', va='bottom')
        plt.text(x, -y2 - 0.05, f'{round(y2, 2)}', ha='center', va='top')

    plt.savefig('./image_dir/bar.png')
    plt.show()

四:等高线图

复制代码
    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)
    '''
    meshgrid函数就是用两个坐标轴上的点在平面上画网格(当然这里传入的参数是两个的时候)。
    当然我们可以指定多个参数,比如三个参数,
    那么我们的就可以用三个一维的坐标轴上的点在三维平面上画网格。
    '''
    X, Y = np.meshgrid(x, y)
    # use plt.contourf to filling contours
    # X, Y and value for (X, Y)point
    plt.contourf(X, Y, f(X, Y), 8, alpha=0.75, cmap='hot')
    # plt.xticks(())
    # plt.yticks(())

    # use plt.contour to add contour lines   8表示分成10份, 0分成2份
    C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=.5)
    # adding label
    plt.clabel(C, inline=True, fontsize=10)
    plt.savefig('./image_dir/contourf.png')
    plt.show()

五 直方图

复制代码
import matplotlib.pyplot as plt
import numpy as np
import matplotlib

def hist1():
    # 设置matplotlib正常显示中文和负号
    matplotlib.rcParams['font.sans-serif'] = ['SimHei']    # 用黑体显示中文
    matplotlib.rcParams['axes.unicode_minus'] = False  # 正常显示负号
    data = np.random.randn(10000)
    '''
    data: 绘图数据
    bins:直方图的长方形数目, 可选项, 默认为10
    normed:是否将得到的直方图向量归一化, 可选项, 默认为0, 代表不归一化, 显示频数。 normed=1,表示归一化,显示频率
    facecolor: 长方形的颜色
    edgecolor: 长方形边框的颜色
    alpha: 透明度
    '''
    plt.hist(data, bins=40, density=1, facecolor='blue', edgecolor='black', alpha=0.7)
    # 显示横轴标签
    plt.xlabel("区间")
    # 显示纵轴标签
    plt.ylabel("频数/频率")
    # 显示图标数
    plt.title("频数/频率分布直方图")
    plt.show()


if __name__ == '__main__':
    hist1()

六 条形图

复制代码
import matplotlib.pyplot as plt
import matplotlib
# 设置中文字体和负号正常显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False

label_list = ['2014', '2015', '2016', '2017']    # 横坐标刻度显示值
num_list1 = [20, 30, 15, 35]      # 纵坐标值1
num_list2 = [15, 30, 40, 20]      # 纵坐标值2
x = range(len(num_list1))
"""
绘制条形图
left:长条形中点横坐标
height:长条形高度
width:长条形宽度,默认值0.8
label:为后面设置legend准备
"""
rects1 = plt.bar(left=x, height=num_list1, width=0.4, alpha=0.8, color='red', label="一部门")
rects2 = plt.bar(left=[i + 0.4 for i in x], height=num_list2, width=0.4, color='green', label="二部门")
plt.ylim(0, 50)     # y轴取值范围
plt.ylabel("数量")
"""
设置x轴刻度显示值
参数一:中点坐标
参数二:显示值
"""
plt.xticks([index + 0.2 for index in x], label_list)
plt.xlabel("年份")
plt.title("某某公司")
plt.legend()     # 设置题注
# 编辑文本
for rect in rects1:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
for rect in rects2:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
plt.show()

七 水平条形图

复制代码
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False

price = [39.5, 39.9, 45.4, 38.9, 33.34]
"""
绘制水平条形图方法barh
参数一:y轴
参数二:x轴
"""
plt.barh(range(5), price, height=0.7, color='steelblue', alpha=0.8)      # 从下往上画
plt.yticks(range(5), ['亚马逊', '当当网', '中国图书网', '京东', '天猫'])
plt.xlim(30,47)
plt.xlabel("价格")
plt.title("不同平台图书价格")
for x, y in enumerate(price):
    plt.text(y + 0.2, x - 0.1, '%s' % y)
plt.show()

八 堆叠条形图

复制代码
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False

label_list = ['2014', '2015', '2016', '2017']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 30, 40, 20]
x = range(len(num_list1))
rects1 = plt.bar(left=x, height=num_list1, width=0.45, alpha=0.8, color='red', label="一部门")
rects2 = plt.bar(left=x, height=num_list2, width=0.45, color='green', label="二部门", bottom=num_list1)
plt.ylim(0, 80)
plt.ylabel("数量")
plt.xticks(x, label_list)
plt.xlabel("年份")
plt.title("某某公司")
plt.legend()
plt.show()

九 饼图

复制代码
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False

label_list = ["第一部分", "第二部分", "第三部分"]    # 各部分标签
size = [55, 35, 10]    # 各部分大小
color = ["red", "green", "blue"]     # 各部分颜色
explode = [0.05, 0, 0]   # 各部分突出值
"""
绘制饼图
explode:设置各部分突出
label:设置各部分标签
labeldistance:设置标签文本距圆心位置,1.1表示1.1倍半径
autopct:设置圆里面文本
shadow:设置是否有阴影
startangle:起始角度,默认从0开始逆时针转
pctdistance:设置圆内文本距圆心距离
返回值
l_text:圆内部文本,matplotlib.text.Text object
p_text:圆外部文本
"""
patches, l_text, p_text = plt.pie(size, explode=explode, colors=color, labels=label_list, labeldistance=1.1, autopct="%1.1f%%", shadow=False, startangle=90, pctdistance=0.6)
plt.axis("equal")    # 设置横轴和纵轴大小相等,这样饼才是圆的
plt.legend()
plt.show()

十 保存image图像:

复制代码
    a = np.random.rand(9).reshape(3, 3)

    plt.imshow(a, interpolation='nearest', cmap='bone', origin='upper')
    plt.colorbar()
    plt.xticks(())
    plt.yticks(())
    plt.savefig('./image_dir/imshow.png')
    plt.show()

十一 画3d图

复制代码
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


def test1():
    fig = plt.figure()
    ax = Axes3D(fig)
    x = np.arange(-4, 4, 0.25)
    print(x)
    y = np.arange(-4, 4, 0.25)
    x, y = np.meshgrid(x, y)
    # np.sqrt(x) : 计算数组各元素的平方根
    R = np.sqrt(x ** 2 + y ** 2)
    # height value
    z = np.sin(R)
    ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap='rainbow')
    # zdir 表示向那个轴投影
    ax.contourf(x, y, z, zdir='z', offset=-2, cmap='rainbow')
    # 设置等高线的高度
    ax.set_zlim(-2, 2)

    plt.show()


if __name__ == '__main__':
    test1()

十二 subplot多图合一

方法一

复制代码
# method1: subplot2grid
    #################
    '''
    第一个参数(3, 3) 是把图分成3行3列
    第二个参数是位置 (0, 0)表示从0行0列开始
    第三个参数  colspan=3  表示列占3列 ,
    第四个参数 rowspan=1  表示行占一行

    '''
    plt.figure()
    ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=3, rowspan=1)
    ax1.plot([1, 2], [1, 2])
    ax1.set_title('al1_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.savefig('./image_dir/grid1.png')
    plt.show()

方法二

复制代码
    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[-1, 0])
    ax5 = plt.subplot(gs[-1, -2])

    plt.savefig('./image_dir/grid2.png')
    plt.show()

方法三

复制代码
    # method4
    plt.figure()
    plt.subplot(2, 2, 1)
    plt.plot([0, 1], [0, 1])
    plt.subplot(222)
    plt.plot([0, 1], [0, 2])
    plt.subplot(223)
    plt.plot([0, 1], [0, 3])
    plt.subplot(224)
    plt.plot([0, 1], [0, 4])
    plt.savefig('./image_dir/grid4.png')
    plt.tight_layout()
    plt.show()

方法四

复制代码
    # method 3 : easy to define structure
    f, ((ax11, ax12), (ax21, ax22)) = plt.subplots(2, 2, sharex=True, sharey=True)
    ax11.scatter([1, 2], [1, 2])
    plt.savefig('./image_dir/grid3.png')
    plt.tight_layout()
    plt.show()

十三 画图中图

复制代码
    fig = plt.figure()
    x = np.arange(1, 9, 1)
    y = np.linspace(1, 10, 8)
    left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
    ax1 = fig.add_axes([left, bottom, width, height])
    ax1.plot(x, y, 'r')
    ax1.set_xlabel('x')
    ax1.set_ylabel('y')
    ax1.set_title('title')

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

    left, bottom, width, height = 0.6, 0.2, 0.25, 0.25
    ax3 = fig.add_axes([left, bottom, width, height])
    ax3.plot(y, x, 'g')
    ax3.set_xlabel('x')
    ax3.set_ylabel('y')
    ax3.set_title('title inside 2')
    plt.savefig('./image_dir/tu1.png')
    plt.tight_layout()
    plt.show()

十四 次坐标轴

复制代码
x = np.arange(0, 10, 0.1)
y1 = 0.5*x**2
y2 = -1*x**2
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='b')
plt.savefig('./image_dir/xy.png')
plt.tight_layout()
plt.show()

十五 animation

复制代码
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
print(len(x))
print(x)
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,


#  func 表示animation的动画, frames表示100个时间点, init_func 表示初始点,
#  inyterval 表示每隔多少时间点刷新 一次, blit是否是全部更新, 如果为FLASE则更新需要更新的点
ani = animation.FuncAnimation(fig=fig, func=animate, frames=100, init_func=init, interval=20, blit=False)

plt.savefig('./image_dir/animation.png')
plt.tight_layout()
plt.show()
相关推荐
历程里程碑1 小时前
Linux 5 目录权限与粘滞位详解
linux·运维·服务器·数据结构·python·算法·tornado
程序员哈基耄2 小时前
安全高效,本地运行:全能文件格式转换工具
大数据·python·安全
lixin5565562 小时前
基于神经网络的音乐生成增强器
java·人工智能·pytorch·python·深度学习·语言模型
养海绵宝宝的小蜗2 小时前
Python第二次作业
开发语言·python
我的xiaodoujiao2 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 43--添加allure测试报告显示信息和其他封装方法
python·学习·测试工具·allure
无垠的广袤2 小时前
【CPKCOR-RA8D1】RUHMI 转换 AI 模型
人工智能·python·嵌入式硬件·开发板
aiguangyuan2 小时前
从词袋到TF-IDF:sklearn文本特征工程实战指南
人工智能·python·nlp
数据知道2 小时前
PostgreSQL 实战:详解 UPSERT(INSERT ON CONFLICT)
数据库·python·postgresql
June bug2 小时前
(#数组/链表操作)寻找两个正序数组的中位数
数据结构·python·算法·leetcode·面试·职场和发展·跳槽