先放出最终的图:
左边是分布直方图,右边是累积概率分布图,黑色的是CDF的包络线
实现步骤如下:
步骤一:将原来的直方图表示成左边这种只显示折线的形式:
首先我们需要实现分布直方图,使用函数plt.hist()
z1=plt.hist(list(my_DF["最短路径的长度"]), 30, normed=1,color="red",alpha=0.75,histtype='step',label="PDF")
代码中的参数分别代表如下的意义:
list(my_DF["最短路径的长度"])是我的数据,
30表示将数据分成30组,
normed=1表示纵轴是概率,如果该参数为False,表示纵轴是频数
color="red"表示线条的颜色
alpha=0.75表示线条颜色的透明程度,alpha越小表示颜色越淡
histtype='step'表示将直方柱并在一起,除边界外颜色透明
label="PDF"表示标签
如果我们不设置参数histtype='step',画出的图如下所示:
步骤二:画出CDF(累积概率分布图)
还是使用函数plt.hist(),具体参数设置如下所示:
z2=plt.hist(list(my_DF["最短路径的长度"]), 30, normed=1, color="b",alpha=0.75,histtype='step',cumulative=True,label="CDF")
前面的参数和画PDF的图一样,不同的设置是:
cumulative=True表示画的是CDF
步骤三:画出CDF的包络线
使用的代码如下:
z2=plt.hist(list(my_DF["最短路径的长度"]), 30, normed=1, color="b",alpha=0.75,histtype='step',cumulative=True,label="CDF")
bin_edges=z2[1][0:len(z2[1])-1]
hist=z2[0]
plt.plot(bin_edges,hist,color='black',linestyle='--')
也就是将plt.hist()函数的返回值赋给变量z2,plt.hist()的返回值z2中第一个z2[0]表示划分的每个bins里面左端点对应的频率值,z2[1]表示每个bins的左端点,然后根据这两个值用plt.plot画出一个曲线,就是CDF的包络线。关于函数hist内参数和返回参数的详细意义见后面的参考链接。
步骤四:将CDF和PDF两张图放在一张图里面
PDF对应纵坐标的范围为【0,16】,而CDF对应的纵坐标对应的范围是【0,100】,如果不做任何调整就把两条线放在一张图里面就会出现下面的情况:
也就是PDF不显示的情况,为了解决这个问题,我们使用双y轴解决
在画PDF和CDF的plt.hist()函数之间加上:ax2 = ax1.twinx()
最终的代码如下所示:
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
plt.rc('font',family='Times New Roman')#设置参数,使得图中所有的字格式为Times New Roman
FontSize=15#统一设置坐标轴上面数字、label、图例中数字和字的大小
#用于下面设置双y轴
fig = plt.figure()
ax1 = fig.add_subplot(111)
#画分布直方图PDF
z1=plt.hist(list(my_DF["最短路径的长度"]), 30, normed=1,color="red",alpha=0.75,histtype='step',label="PDF")
#设置x轴上面显示的度量
x_1=list(range(0,200,25))
#因为原来x轴的显示范围为[0,20000],所以下面函数第一个参数为对应的值和显示值的个数,第二个参数是我们需要x轴上显示的数字,两个参数值的个数必须一样
plt.xticks([i*100 for i in x_1],[float(i)/10 for i in x_1],fontsize=FontSize)
#设置x轴上面显示的度量
y_1=[i*2 for i in range(9)]
plt.yticks([i*0.00001 for i in y_1],y_1,fontsize=FontSize)
#设置x、y轴上显示的label
plt.xlabel('Segment Length(km)',fontsize=FontSize)
plt.ylabel('Percentage(%)',fontsize=FontSize)
plt.legend(fontsize=FontSize,loc='center right') # 标签位置
#背景中显示灰色的方格
plt.grid()
#设置第二个轴
ax2 = ax1.twinx()
#画CDF
z2=plt.hist(list(my_DF["最短路径的长度"]), 30, normed=1, color="b",alpha=0.75,histtype='step',cumulative=True,label="CDF")
#画CDF的包络线
bin_edges=z2[1][0:len(z2[1])-1]
hist=z2[0]
plt.plot(bin_edges,hist,color='black',linestyle='--')
#设置第二个y轴的显示度量
y_2=list(range(0,12,2))
plt.xticks(fontsize=FontSize)
plt.yticks([i*0.1 for i in y_2],[i*10 for i in y_2],fontsize=FontSize)
#设置x、y轴的label
plt.xlabel('Segment Length(km)',fontsize=FontSize)
plt.ylabel('Percentage(%)',fontsize=FontSize)
#设置label大小和位置
plt.legend(fontsize=FontSize,loc='lower right')
plt.show()
上面的代码显示的就是最开始的图。
参考文献:
(1)关于绘制直方图时hist的内部参数以及返回参数的意义:
https://blog.csdn.net/qq_41940950/article/details/82937966
https://blog.csdn.net/tian_tian_hero/article/details/85245424
(2)x、y轴标签的显示位置:
https://www.jianshu.com/p/7260ad5181de
(3)多种方法画数据的CDF:
https://blog.csdn.net/tian_tian_hero/article/details/85245424
(4)画出直方图的包络线
https://blog.csdn.net/baidu_15113429/article/details/55100236
(5)关于设置双y轴:
https://blog.csdn.net/castinga3t/article/details/79217270
https://blog.csdn.net/autoliuweijie/article/details/51594373
https://blog.csdn.net/castinga3t/article/details/79217270