matplotlib basic and boxplot(matplotlib画图)

网友投稿 290 2022-09-05


matplotlib basic and boxplot(matplotlib画图)

如果需要考虑绘图性能开销的话, 可以考虑PyQtGraph (比matplotlib更高效, 适用于开发实时更新数据的图表,如Tick图、K线图、期权波动率曲线.

============================================

matplotlib 绘图基础

============================================

绘图: matplotlib核心剖析

Python图表绘制:matplotlib绘图库入门

Matplotlib Tutorial(译)

Use of Matplotlib

这个文章比较多地讲述了marker style和线型设置

(HYRY Studio 出品)

coords (0,0 is lower-left and 1,1 is upper-right)

data coords, data 值的坐标系

figure coords,

============================================

boxplot 绘图

============================================

理解统计学上的boxplot

它以step by step的方式, 告诉我们如何调教matplotlib绘制boxplot图.

============================================

我的笔记

============================================

matplotlib中boxplot常用的术语:

whiskers, 是指从box 到error bar之间的竖线

fliers, 是指error bar线之外的离散点. 维基上的叫法是 Outliers

caps, 是指error bar横线

boxes, Q1 和 Q3组成的box, 即25分位和75分位.

medians, 是中位值的横线.

means, 是avg的横线.

ax.boxplot() 函数参数:

-参数x: data的输入, 格式是: 由vector组成的一个list

-参数whis: 用来确定 error bar的位置,  上面的那条error bar的位置等于: Q3 + whis*IQR, 下面的那条error bar的位置等于 Q1-whis*IQR, 其中IQR = interquartile range 即 Q3-Q1, whis缺省值为1.5.

-绘图风格参数, 这些参数有: boxprops,flierprops, medianprops, meanprops,capprops,whiskerprops属性.

每个绘图风格属性都是dict对象, 下面是一个比较完整属性设定,

dict(linestyle='solid', color='blue', linewidth=1, marker='o', markerfacecolor='red', markeredgecolor='black', markeredgewidth=3, markersize=12)

matplotlib 在画boxplot时候, 先对原始数值序列X, 使用cbook.boxplot_stats()来求得median/q1/q3等值, 然后根据这些统计值来绘图. 如果我们对boxplot上的各个坐标存疑, 也可以手工调用 my_bxpstats=cbook.boxplot_stats()来验证这些统计值是否合理. my_bxpstats的属性有:

med: 中位值.

q1: box的下边界, 即25分位值.

q3: box的上边界, 即75分位值.

whislo: 下面的那条error bar值.

whishi: 上面的那条error bar值.

有时候单纯ax.boxplot()函数不能满足需求, 比如我们需要将各个box的avg点连起来. 这时候我们可以通过boxplot()函数的返回对象, 获取各个绘图元素对象, 有了这些基本绘图对象, 即可画出我们自定义的绘图元素.  下面以bp作为boxplot()返回对象.

bp的基本绘图元素有:

boxes, 是25分位值和75分位值构成的box, 每个box是一个PathPatch对象

medians, 是中位值的横线, 每个median是一个Line2D对象

whiskers, 是指从box 到error bar之间的竖线. 每个whisker是一个Line2D对象

fliers, 是指error bar线之外的离散点. 每个flier是一个Line2D对象

caps, 是指error bar横线. 每个cap是一个Line2D对象

means, 是avg的横线, 每个mean是一个Line2D对象

一旦能访问到这些Line2D对象, 就可以做更多的定制化了, 比如设置线性/颜色等, 因为有了位置信息, 甚至可以派生出其他Line2D对象. boxplot函数没有参数控制隐藏中位线, 如果我们需要隐藏, 可以将linewidth设为0

================

几点注意事项

================

##理解target_line, = ax.plot(x,y) 中的逗号

在matplotlib示例代码中, 我们经常看到将ax.plot()赋值给 "var," 这样的写法, 比如,

target_line, = ax.plot([0,  10 + 0.5], [10, 10], linestyle='-', color='red', linewidth=2, label='Target')

如果我们清楚ax.plot() 函数返回一个单元素的list, 上面的写法就很好理解了, 这其实就是一个unpack操作, 这之后target_line即是这个单元素.

##为ax上的多个绘图元素增加增加legend,

比如为boxplot和一条Line, 这里需要使用ax.legend()函数, 代码如下:

box = bp["boxes"][0]  # 获取箱线图中的第一个box, 作为legend标示的绘图对象.

ax.legend((box,target_line), ("Box plot","Target line"),

fontsize=7, frameon=False,

loc='upper left', bbox_to_anchor=(1.0, 1.0))

##调整边框空白

通常如果一个fig上只有一个ax的话, 边框显得很宽, 默认边框约有0.1个axis坐标系单位, 需要手动调整一下.

ax = fig.add_subplot(1, 1, 1)

plt.subplots_adjust(left=0.03, right=0.94, bottom=0.14, top=0.93)

##设置背景色

#set ax background color

ax.set_axis_bgcolor('#D4D0C8')

#set fig background color

rect = fig.patch

rect.set_facecolor('#D4D0C8')

对应的savefig()时候, 需要指定facecolor, 否则图片上ax将带背景色, 而fig其他部分为白色.

fig.savefig(self.trend_chart_full_file, dpi=200, facecolor=fig.get_facecolor(), edgecolor='none')

# 有时候matplotlib给出的默认的xtick数量很少, 而我们需要标注的xtick_labels又太多,  就需要调整major tick的数量.

# 如果major tick数量超1000的话, 还需要重置locator.MAXTICKS值.

main_plot, = ax.plot(data_to_plot, marker='s', markersize=3, color='green', linewidth=1)

ax.tick_params(labelsize=6)

value_count = len(data_to_plot)

if value_count < 1000:  # 1000 is the default tick.MAXTICKS

ax.locator_params(axis='x', nbins=value_count)

else:

x_locator = ax.xaxis.get_major_locator()

x_locator.MAXTICKS = value_count + 5     # 手动调整 MAX ticks的数量, 否则matplot会抛异常

ax.locator_params(axis='x', nbins=value_count)

ax.set_xticklabels(xtick_labels)

# xlabel太密集了, 坐标轴上的刻度文字会重叠的, 需要隔几个刻度显示一个刻度文字, 可以使用MultipleLocator, LinearLocator等, 但都很难用, 下面的代码很简单, 先全部隐藏, 然后将需要的刻度文字显示出来即可.

ticks_count = len(collectn_list)

ax.locator_params(axis='x', nbins=ticks_count) # set major ticks number

ticks_count_visible = 15  # show 15 ticks at most

interval = int(ticks_count / ticks_count_visible) + 1

for label in ax.xaxis.get_ticklabels():

label.set_visible(False)

for label in ax.xaxis.get_ticklabels()[0::interval]:

label.set_visible(True)

#matplotlib 坑: ax.set_xticklabels() 函数有时候会报错, 猜测因为ticks太多, 需要catch一下.

# noinspection PyBroadException

try:

ax.set_xticklabels(xtick_labels)

except Exception as ex:

self.logger.exception(ex)

#matplotlib 坑:plt.clf() 有时候会报错, 简单封装一个clf_safely()函数

@classmethod

def clf_safely(cls):

import matplotlib.pyplot as plt

# noinspection PyBroadException

try:

plt.clf()  #

except Exception as ex:

cls.logger.exception(ex)

============================================

一个示例

============================================

下面代码是一个定制的boxplot, 定制点有:

1. 绿色的 avg line

2. 需要从最大值连一条线到box顶, 需要从最小值连一条线到box底

3. 画三条水平虚线, 分别是target/UCL/LCL

## numpy is used for creating fake dataimport numpy as npimport matplotlib as mpl## agg backend is used to create plot as a .png filempl.use('agg') # must set before import matplotlib.pyplot import matplotlib.pyplot as plt## 初始化raw data以及其他信息collectn_list = [] # raw data#xtick_labels = ['Sample%d'%i for i in range(len(collectn_list))]#y_label ='y_label'#title='title'#target = 80.0#ucl=110.0#lcl=40.0 if not collectn_list: np.random.seed(10) collectn_1 = np.random.normal(100, 10, 20) collectn_2 = np.random.normal(80, 30, 20) collectn_3 = np.random.normal(90, 20, 20) collectn_4 = np.random.normal(70, 25, 20) ## combine these different collections into a list collectn_list =[collectn_1,collectn_2,collectn_3,collectn_4] xtick_labels = ['Sample%d'%i for i in range(len(collectn_list))] y_label ='y_label' title='title' target = 80.0 ucl=110.0 lcl=40.0 data_to_plot = collectn_list# Create a figure instanceplt.clf()fig = plt.figure(figsize=(9, 6)) #设置长为9 inch, 宽为6 inchax = fig.add_subplot(1,1,1)plt.subplots_adjust(left=0.03, right=0.93, bottom=0.15, top=0.93)# grid onax.grid(True)

# set background colorax.set_axis_bgcolor('#D4D0C8')rect = fig.patchrect.set_facecolor('#D4D0C8')# avg line is in greenmeanprops=dict(linestyle='solid', color='green')# hide the default median linemedianprops=dict(linestyle='solid', color='white')# Create the boxplotbp = ax.boxplot(data_to_plot, meanline=True, showmeans=True, meanprops=meanprops, medianprops=medianprops, showcaps=False)## extra line from box top to max point, line from box bottom to min point# 注意几个坐标点的求值for i, collectn in enumerate(collectn_list): percentile_25= np.percentile(collectn, 25, interpolation=b'linear') percentile_75= np.percentile(collectn, 75, interpolation=b'linear') y_max= max(collectn) y_min= min(collectn) medians_org = bp['medians'][i] medians_org_x=medians_org.get_xdata() # array([ 0.8875, 1.1125]) center_x = medians_org_x[0]+(medians_org_x[1]-medians_org_x[0])/2.0 ax.plot([center_x,center_x], [y_min,percentile_25], color='blue') ax.plot([center_x,center_x], [percentile_75,y_max], color='blue') ax.set_xticklabels(xtick_labels)ax.get_xaxis().tick_bottom()ax.get_yaxis().tick_left() ax.set_ylabel(y_label) ax.set_title(title)## add target/UCL/LCL dash line# 注意横线的坐标求值, 和文本的坐标的求值ax.plot([0,len(collectn_list)+0.5],[target,target], linestyle='--', color='blue', linewidth=1) ax.text(len(collectn_list)+0.5,target,"Tgt %.2f"%target,fontsize=10,horizontalalignment='right')ax.plot([0,len(collectn_list)+0.5],[ucl,ucl], linestyle='--', color='blue', linewidth=1) ax.text(len(collectn_list)+0.5,ucl,"UCL %.2f"%ucl,fontsize=10,horizontalalignment='right')ax.plot([0,len(collectn_list)+0.5],[lcl,lcl], linestyle='--', color='blue', linewidth=1) ax.text(len(collectn_list)+0.5,lcl,"LCL %.2f"%lcl,fontsize=10,horizontalalignment='right') fig.show()plt.close(fig) # 调用plt.close()释放内存, plt.clf()并不会释放内存


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:pyDbRowFactory -- Python版Db Row Factory
下一篇:Java GUI插入图片不显示问题解决方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~