用matplotlib画带条纹的直方图经验总结

一、如何画带条纹的直方图

1
2
3
4
5
6
7
8
9
10
11
from matplotlib import pyplot as plt
color = [(0.3098, 0.5059, 0.74120), (0.6078, 0.7333, 0.3490), (0.7490, 0.3137, 0.3020),\
(0.50, 0.50, 0.50), (0.93, 0.69, 0.13), (0.30, 0.75, 0.93),\
(0.50, 0.39, 0.64), (0.15, 0.15, 0.15), (0.18, 0.64, 0.54)]
patterns = ['/', '\\', 'xx', 'x', '\\\\', '//', '+', '..', '++']
Data = [1234] # 需要画直方图的一组数
X = 1 # 第一个柱子的中轴x坐标
INTERVAL = 1.6 # 柱子之间的间隔
WID = 1 # 柱子宽度
for i in range(len(Data)):
plt.bar(X+i*INTERVAL, Data[i], width = WID, facecolor = 'white', edgecolor = color[i], hatch=patterns[i])

X+i*INTERVAL 是第i个柱子的轴中心坐标,facecolor是柱子的填充颜色,edgecolor是柱子边缘以及条纹的颜色,特别的,这里颜色既可以通过单词或者缩写来选择标准色(比如上面facecolor那一栏),又可以通过RGB来自定义颜色。

hatch参数是柱子可以添加的填充图案款式,如果缺省就是实心柱子,一共有

1
['-', '+', 'x', '\\', '/', '*', 'o', 'O', '.']

这些款式,每种又都可以重复一遍来表示更密的条纹。上面的例子程序中我主要找了一些我觉得画出来比较好看的颜色和条纹样式。

二、如何改线宽

plt.bar()函数自带了参数linewidth,通过设定linewidth可以改变柱子外延的线宽度,但是却无法改变条纹的线宽,通过查资料我找到在matplotlib版本2.1.2以上可以直接改rcParams[‘hatch.linewidth’]这个参数,方法如下:

1
2
3
4
5
import matplotlib as mpl
lw = 2 # 设置一个全局的线宽方便修改
mpl.rcParams['hatch.linewidth'] = lw
for i in range(len(Data)):
plt.bar(X+i*INTERVAL, Data[i], linewidth=lw)

三、如何设置legend

这篇文章讲的非常清楚https://blog.csdn.net/qq_33221533/article/details/81431264

这里讲几个自己用到的:

1
plt.legend(legend_list, fontsize = FontSize1, loc=lo, fancybox = False, edgecolor='black', borderpad = 0.2, labelspacing = 0.2, handletextpad = 0.3, ncol = nco)
参数 功能
fontsize legend的字体大小
loc legend的位置,0:自动寻找最佳,1:右上,2:左上,3:左下,4:右下,5:正右,6:左中,7:右中(感觉和右没啥区别),8:正上,9:正下,10:正中
fancybox 缺省情况下legend是圆角,改为False后为直角
edgecolor 边框颜色
borderpad 图例边框的内边距
labelspacing 图例条目之间的垂直间距
handletextpad 图例句柄的长度
ncol 图例分为n列展示

四、如何设置输出格式为PDF

写论文的时候需要矢量形式的图,但是不知道为什么输出eps格式后,eps文件保存的图像总是出错,所以考虑用pdf来保存:

1
2
3
from matplotlib.backends.backend_pdf import PdfPages
pdf = PdfPages('figure1.pdf')
pdf.savefig()

五、如何在加label后输出正确长宽比的图

plt.figure()函数中figsize参数只决定了画布的长宽比,但是如果你的图上加了Label等标识,就会占用画布面积,导致主体图的比例不再是你最开始想要取的比例。我的解决方案是通过移动主体图给标注留出足够的固定空间,再通过计算得出要使主体图满足预期长宽比的画布长宽比。下面以只加一个Y轴的label为例:

1
2
# 假定我们想要的主体图的长宽比是1:1
x = 0.2 # 这是我们给Y-label留出的横向长度的百分比

接下来就是一个简单的初中几何

可以看到我们现在的长宽比变成了1:(1-x),那么接下来就简单了:

1
2
3
4
5
6
7
# 假定我们想要的主体图的长宽比是1:1
x = 0.2 # 这是我们给Y-label留出的横向长度的百分比
fig = plt.figure(figsize=((1/(1-x)),1), dpi = 100)
'''
此处省略正常绘图步骤
'''
plt.subplots_adjust(left=x) # 这一步实现的就是前面说的“移动主体图给标注留出足够的固定空间”,这里表示的是主体图左边空出了总画布比例x的空白(用来放ylabel)