Matplotlib 绘制多子图(subplot)进行实验结果分析


  本文主要总结于本人近期的科研经历,在最后撰写论文试验分析的时候曾经被导师要求绘制一幅2*8的16子图的超参数分析结果图。所以踩了很多坑,在这里给出简单的实现方式,本文使用的子图以折线图为例,其他的类型的图都可以举一反三。当然为了使结果呈现得更加美观简洁,本文在最后也介绍了一点如何调整刻度的小技巧。

预备工作

前期环境配置

  pycharm-2021.2.2, python-3.7, matplotlib-3.2.2, numpy-1.20.2 具体其实只要有这几个版本的包就行了,更高版本推测应该也没事。导包:

import numpy as np
import matplotlib.pyplot as plt

准备数据

  个人建议使用np.array来准备数据,这样可以随时确认数据的格式。例如本文就采用如图1所示的格式,来存储准备打印的数据,只不过这里是为了简单实验所以都用了相同的数据,到时候真的要做实验分析图的话,肯定是把真实的实验数据放上。如下所示,为2*4的图准备数据。

demo_data = np.array([82.51, 77.66, 81.92, 83.48, 78.95])

配置图表所需的字体

  如果所投的期刊或会议有要求,那么这一步设置是很重要的,要使图标坐标轴上、图例的字体以及显示的字体与论文正文一致起来。注意这里需要以dict() 的类型来定义字体,另外还需要注意单独定义坐标轴上刻度的字体大小。如:

default_font = {'family': 'Times New Roman', 'weight': 'normal', 'size': 14}
tick_font = 12  # 坐标轴上字体大小

构建Figures

设置子图布局器

  首先需要定义整个布局框架和子图component,代码如下:

plt.subplots(2, 4, figsize=(12, 4), dpi=100)

  其中,第一个参数为子图的行数,第二个参数为列数。第三个参数figsize就如同我们定义单张matplotlib图时一样是表示画布的大小,如代码所示就是宽1600*高400的size,dpi越高则图像被放大后的失真率越小。

调整边距

  同时我们需要在这里就对图片的边距进行调整,当然如果这6个值一开始设计的不理想,可以在打印出结果后根据自己的视觉感觉慢慢调整。如下代码:

plt.subplots_adjust(top=0.97, bottom=0.2, left=0.05, right=0.995, hspace=0.6, wspace=0.5)

  其中,top值越接近1则子图距离顶部越接近,bottom值越接近于0则子图距离底部约接近,left值越接近于0则子图距离左边框越接近,right值越接近于1则子图距离右边框越接近,而hspace指的是两行子图之间的间距,值越大则两行之间距离越高,同理wspace指的是两列子图之间的距离,值越大距离越大。

定义子图

plt.subplot(241)

  Subplot方法中可以这样写,这表示定义当前子图为1号图属于2*4的子图阵列。当然也可以写作:

plt.subplot(2, 4, 1)

  加上逗号的好处是可以避免如果你需要定义2行5列,或十张以上子图,如subplot(2510)时,编译会报错的情况,当你打算定义10张以上子图的时候必须加逗号来区分(行数,列数和子图编号)这三个数字了(2, 5, 10),而不能直接写2510。此时,当着行代码被执行的时候就代表目前plt已经将布局器定位到了当前子图下,此时再使用plt进行修改的就是当前子图了。(直到代码执行到下一句plt.subplot(***)的时候,plt才会结束定义当前子图)

  定义好当前子图就可以开始定义子图内部的结构了,这里以折线图为例子,还可以换成饼图,柱状图,散点图或是3D图。

axis_x_1 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_1, demo_data, color='darkred', linestyle='-', linewidth=2, marker='o',markeredgecolor='darkred', markersize='4', markeredgewidth=2)

  其中plot函数是主要的绘图函数,它代表着线图的主体,其中第一个参数定义着横轴接受数据的范围,比如我们刚刚定义的输入是5个数值,所以这里定义axis_x为np.arrange(1, 6)表示要接受5个值来展示,而第二个参数代表的就是具体的那五个数的数据了。至于后面的参数是一些修饰性质的,大家可以自行查阅文档来了解使用,无非就是主线条配色、主线条粗细、结点形状、结点线条样式,当然为了方便大家查询,我在Reference部分放置了颜色和形状参照表,并且在本文中8个图里也使用了四种不同的但是常用的颜色和形状表示。(补充,如果需要给图添加图例,可以在其中添加参数label=”label text”来实现)

  在定义绘图部分后,要尝试为子图添加坐标轴和横纵坐标描述,如下代码:

plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)

  其中横纵坐标轴ticks的区间也建议使用np.arrange来定义,关于横坐标,我建议使用输入数据的公因数来绘制会比较美观,比如我的输入是10个数据,那么我可以选择每两个数据记一个刻度,np.arrange(0, 10.1, 2)(注意:这里写10.1是为了让10显示出来)当然如果你只有五个数据需要显示的话,可以直接像我代码中写的一样写成np.arrange(1, 6)来直接绘制5个刻度。纵坐标如何显示的美观呢,也是同样的法子,首先去观察你的输入数据他们最大值和最小值相差多少,然后将这个差除以5,就是间距应该设置多少。比如,我在代码中举的例子:我的数据最大的是83.48最小的是77.66,这时候我们将np.arrange的下限设为75(略低于最小值),上限设为85.1(略高于最大值,且+0.1为了显示出85这个刻度),间距设置为2,就可以美观的铺设五个刻度,并且尽可能的让我们的图像位于中央。

  而xlabel中填写的就是坐标轴刻度的含义了,其中大家可以使用$ text $的方式是中间的text变为斜体,这是很有用的,比如在绘制超参数实验图的时候,往往我们定义的参数在Latex中都是倾斜体,为了一致起来,这里也要这样修改。并且善用\n换行符也可以让图变得更加美观。

保存图像

plt.savefig('demo.eps', bbox_inches='tight')
plt.show()

  不要忘记保存和显示绘制好的图像,Latex插入图像建议使用.eps格式,所以我在输出的时候采用的.eps,当然你也可以改成.png或是.jpg都没关系,其中的参数bbox_inches是表示以什么样的边距输出图像,tight是最窄边距,不过这个参数在你自定义设置了边距时效果不明显,当你没有自己设置边距,而画布有定义的比较大的时候,这个参数就很有效果了。同时需要注意的是如果你想一边保存一边在Pycharm里查看即时生成的效果图,那么这个plt.show是要放在保存之后的,不然有时会出错。

完整代码

import numpy as np
import matplotlib.pyplot as pltdemo_data = np.array([82.51, 77.66, 81.92, 83.48, 78.95])default_font = {'family': 'Times New Roman', 'weight': 'normal', 'size': 14}
tick_font = 12  # 坐标轴上字体大小plt.subplots(2, 4, figsize=(12, 4), dpi=100)
plt.subplots_adjust(top=0.97, bottom=0.2, left=0.05, right=0.995, hspace=0.6,wspace=0.5)# 画第1个图:
plt.subplot(241)
axis_x_1 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_1, demo_data, color='darkred', linestyle='-', linewidth=2, marker='o',markeredgecolor='darkred', markersize='4', markeredgewidth=2)
plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)# 画第2个图:
plt.subplot(242)
axis_x_2 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_2, demo_data, color='darkred', linestyle='-', linewidth=2, marker='o',markeredgecolor='darkred', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)# 画第3个图:
plt.subplot(243)
axis_x_3 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_3, demo_data, color='navy', linestyle='-', linewidth=2, marker='v',markeredgecolor='navy', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)# 画第4个图:
plt.subplot(244)
axis_x_4 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_4, demo_data, color='navy', linestyle='-', linewidth=2, marker='v',markeredgecolor='navy', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)# 画第5个图:
plt.subplot(245)
axis_x_5 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_5, demo_data, color='darkorange', label="label text", linestyle='-', linewidth=2, marker='s',markeredgecolor='darkorange', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 5.1, 1), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)
plt.legend(loc='upper left')    # 定义图例显示的位置# 画第6个图:
plt.subplot(246)
axis_x_6 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_6, demo_data, color='darkorange', label="label text", linestyle='-', linewidth=2, marker='s',markeredgecolor='darkorange', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 5.1, 1), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)
plt.legend(loc='upper right')# 画第7个图:
plt.subplot(247)
axis_x_7 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_7, demo_data, color='darkgreen', linestyle='-', linewidth=2, marker='D',markeredgecolor='darkgreen', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)
plt.grid(True)# 画第8个图:
plt.subplot(248)
axis_x_8 = np.arange(1, 6, dtype=np.float32)
plt.plot(axis_x_8, demo_data, color='darkgreen', linestyle='-', linewidth=2, marker='D',markeredgecolor='darkgreen', markersize='4', markeredgewidth=2)
plt.xlabel('Values of $K$\n(a) Text here', default_font)
plt.ylabel('Text here ', default_font)
plt.xticks(np.arange(1, 6), fontsize=tick_font)
plt.yticks(np.arange(75, 85.1, 2.0), fontsize=tick_font)
plt.grid(True)plt.savefig('demo.eps', bbox_inches='tight')
plt.show()

效果图

Reference

[1] 表格和图例的参考:https://blog.csdn.net/HangoverLG/article/details/106044304
[2] 颜色和形状参考表:https://blog.csdn.net/The_Time_Runner/article/details/102599891

【科研分享】Matplotlib 绘制多子图(subplot)进行实验结果分析相关推荐

  1. Python Matplotlib绘制多子图准备训练数据和GIF动画实践

    我们程序员.设计人员,按需求辛辛苦苦开发出来的统计图形,往往达不到用户的要求,原因一般是表达不全面,也有内容过多而比较乱,真是众口难调. 其实,是我们表达方式与业务人员工作脱节.业务人员看了一张图或及 ...

  2. matplotlib绘制多子图共享鼠标光标

    matplotlib官方除了提供了鼠标十字光标的示例,还提供了同一图像内多子图共享光标的示例,其功能主要由widgets模块中的MultiCursor类提供支持. MultiCursor类与Curso ...

  3. Matplotlib 绘制 双轴 图

    Matplotlib 绘制 双轴 图 创作背景 分析思路 总结 结尾 创作背景 最近本菜鸡想要画一个 双轴图 ,可是直接使用 plt.plot() 实现不了这个功能,无奈,菜嘛,所以只能去 Matpl ...

  4. 【matplotlib笔记】plt.subplot()绘制子图

    绘制子图 面向过程的方式绘图 如何绘制如下的图呢? 上半部分:看做2行2列,第1行第1列.第1行第2列分别放一张图 下半部分:看做2行1列,第2行的1列放一张图 通过plt.subplot()绘制子图 ...

  5. 如何理解subplot绘制不规则子图的参数设置

    在matplotlib下,一个Figure对象可以包含多个子图(Axes),可以使用subplot()快速绘制,其调用形式如下 subplot(numRows, numCols, plotNum) 图 ...

  6. 【python】python matplotlib绘制并保存多张图片+绘制多张子图

    需求描述:画图对比观测值和预测值,绘制对比图及多张子图 绘制对比图 示例代码 import matplotlib.pyplot as plt import numpy as npobs_x_data ...

  7. Matplotlib——绘制多个子图(Axes)及其布局

    本文介绍如何用matplotlib绘制多个子图,并介绍控制它们布局的方法.按照其布局方式,分为均一排布,规整排布和跨行列排布三种. 一.均一排布plt.subplots() 均一排布的含义:所有子图的 ...

  8. python使用matplotlib可视化subplots子图、subplots绘制子图、子图之间有重叠问题、使用subplots_adjust函数合理设置子图之间的水平和垂直距离

    python使用matplotlib可视化subplots子图.subplots绘制子图.子图之间有重叠问题.使用subplots_adjust函数合理设置子图之间的水平和垂直距离(vertical/ ...

  9. python用for循环画多个图形_Python matplotlib读取excel数据并用for循环画多个子图subplot操作...

    Python matplotlib读取excel数据并用for循环画多个子图subplot操作,英语,总分,平均,数据,语文 Python matplotlib读取excel数据并用for循环画多个子 ...

最新文章

  1. kalman滤波的解释
  2. java 中的sql.date_SQL DATE中的时区vs java.sql.Date
  3. 关于lwip中pbuf_alloc()内存申请函数
  4. 飞鸽传书:HTML界面也有它欠缺的方面
  5. 博客远非“第五力量”
  6. LINUX的一些简单命令 时间修改
  7. 基于JAVA+SpringMVC+MYSQL的ktv预订管理系统
  8. 使用过的MySql查询语句[待续...]
  9. c语言程序设计 实验十一,C语言实验十一 结构体程序设计(二)
  10. Hive-1.2.0学习笔记(四)Hive表管理
  11. centos mysql 二进制_CentOS 7.6 安装二进制Mysql
  12. 抖音地球html代码,抖音短视频征服海外 1/6的地球移动网民活跃
  13. JS动态加载JSON文件并读取数据
  14. 产品必会的30个Axure使用技巧
  15. vue2.0 axios封装
  16. 专业显卡深度学习_MacOS+AMD-eGPU打造深度学习环境 | 第2期
  17. am解调matlab程序,AM调制解调的matlab仿真
  18. 第0期-前言-学习软件测试是否需要培训
  19. 1.Series和DataFrame
  20. 会议纪要模板----正式文档

热门文章

  1. R-loop及两种测序技术的介绍
  2. selenium安装及在python中简单使用
  3. -webkit-tap-highlight-color
  4. H3C官方模拟器HCL(H3C Cloud Lab)
  5. 使用pygame前的小插曲
  6. 我想看的是美胸和大长腿,你却给我直播写代码?
  7. 关于ffmpeg如何下载、安装和使用
  8. 网络安全红队常用的攻击方法及路径
  9. 计算机专业考研复试上机算法学习
  10. ModelSim 实用知识:优化,SDF,覆盖率