先上效果图
代码:
import matplotlib.pyplot as plt import seaborn as sns from matplotlib.ticker import MultipleLocator class Histplot: def __init__(self, y_data, x_data, linetype='ro-', legends=None,title=None, xlabel=None, ylabels=None, fsize=(20, 15), df_line=1): """ :param x_data: 数据x列表 :param x_data: x的分组数 :param linetype: 累计频率曲线的样式,默认为红色实心点 :param legends: 图例名,默认为 "线性拟合结果", "实测值" :param xlabel:x坐标轴标题名,默认为 "数据x" :param ylabels:双y坐标轴标题名,默认为 "计数", "累计频率" :param df_line:是否显示累计频率曲线 """ if legends is None: legends = ["频率", "累计频率"] if xlabel is None: xlabel = "延时" if ylabels is None: ylabels = ["频率", "累计频率"] self.y_data = y_data self.x_data = x_data self.linetype = linetype self.fsize = fsize self.title = title self.legends = legends self.xlabel = xlabel self.ylabels = ylabels self.df_line = df_line def change_legend(self, new_legends): # 将图例名称改为new_legends self.legends = new_legends def change_ylabel(self, new_labels): # 将双y轴坐标轴标题改为new_labels self.ylabels = new_labels def change_xlabel(self, new_label): # 将x轴坐标轴标题改为new_label self.xlabel = new_label def change_title(self, title): # 将x轴坐标轴标题改为new_label self.xlabel = title def change_linetype(self, new_linetype): # 将累计频率线的格式改为new_lintype self.linetype = new_linetype def draw_plot(self): fs = self.fsize # 画布大小 # 利用seaborn库对字体大小进行统一设置,为fgsize[1]的0.12倍,即画布纵向大小为1000时,font_scale=1.2 sns.set_style("ticks") sns.set_context("talk", font_scale=fs[1]*0.11) plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置画布 fig, ax = plt.subplots(figsize=fs) ax.spines['top'].set_visible(False) print(y_data) plt.bar(x_data, y_data, alpha=0.6, width=0.5, facecolor='red', edgecolor='yellow', lw=1) ax.set_xlabel(self.xlabel) ax.set_ylabel(self.ylabels[0]) for a, b in zip(x_data, self.y_data): plt.text(a, b + 0.00005, '%.4f%%' % (b * 100), ha='center', va='bottom', fontsize=10) # ax2:绘制累计频率曲线,可选 if self.df_line: # leiji_n = [sum(n[:i]) / len(self.x_data) for i in range(len(n) + 1)] leiji_n = [sum(self.y_data[:i]) for i in range(len(self.y_data)+1)] print(leiji_n) ax2 = ax.twinx() x_data1 = [i for i in range(11)] ax2.plot(x_data1, leiji_n, self.linetype, ms=fs[0]*0.5, markeredgecolor='g') ax2.set_ylim(0, 1) ax2.set_ylabel(self.ylabels[1]) for a, b in zip(x_data1[1:-1], leiji_n[1:-1]): plt.text(a, b - 0.03, '%.4f%%' % (b * 100), ha='center', va='top', fontsize=9) ax.set_title('频率直方图',pad=30) x_major_locator = MultipleLocator(1) ax=plt.gca() ax.spines['top'].set_color('none') # #ax为两条坐标轴的实例 ax.xaxis.set_major_locator(x_major_locator) ax.axes.get_xaxis().set_visible(False) # 显示多图例 # fig.legend(loc=1, bbox_to_anchor=(1, 1), bbox_transform=ax.transAxes) fig.tight_layout() plt.show() if __name__ == "__main__": raw_data = [6321,9317, 49600, 3250, 0, 1, 0, 0, 0, 2] y_data = [float('%.5f' % (raw_data[i] / sum(raw_data))) for i in range(len(raw_data))] x_data = [i for i in range(1,11)] plot1 = Histplot(y_data, x_data=x_data, fsize=(10, 6.18)) plot1.draw_plot()