https://blog.csdn.net/m0_56069948/article/details/122285951
https://blog.csdn.net/m0_56069948/article/details/122285941
诈尸人口回归。这一年忙着灌水忙到头都掉了,最近在女朋友的提醒下终于想起来博客的账号密码,正好今天灌水的时候需要画一个双X轴双Y轴的图,研究了两小时终于用Py实现了。找资料的过程中没有发现有系统的文章,反正代码都整理出来了,我决定顺势水一篇。
目前找到的plt实现双X轴双Y轴绘图方式有两种:
fig.add_subplot
方式将两对坐标系叠加在一个fig上实现双X轴双Y轴效果。所有调整均可完美实现,推荐该方式axes.twinx().twiny()
方式实现双X轴双Y轴图形绘制。问题在于对于第二个Y轴的各种设置无效,label可以通过手动添加的方式创建并指定颜色,而tick颜色则无法修改。可能需要等待官方修复,或者尝试先使用 ax1=axes.twinx()
方式,从ax1
中获取第二个Y轴,然后再使用ax2.twiny()
创建第二个X轴。
| | """ |
| | 使用plt,通过fig.add\_subplot方式将两对坐标系叠加在一个fig上实现双X轴双Y轴效果。 |
| | 所有调整均可完美实现,推荐该方式 |
| | """ |
| | import matplotlib.pyplot as plt |
| | import numpy as np |
| | |
| | """生成数据并设置绘图参数""" |
| | x = np.arange(1, 12, 4) |
| | y = np.arange(1, 4, 1) |
| | x2=x*10 |
| | y2=y**2 |
| | # 设置两种绘图颜色 |
| | c1='r' |
| | c2='b' |
| | # 设置字体大小 |
| | fontsize=12 |
| | # 设置画布大小 |
| | width,height=16,14 # 单位为cm;因为保存图片时使用 bbox\_inches = 'tight' 可能使图片尺寸略微放大,所以此处宽度设置得略小 |
| | # 设置刻度线在坐标轴内 |
| | plt.rcParams['xtick.direction'] = 'in' |
| | plt.rcParams['ytick.direction'] = 'in' |
| | """绘图""" |
| | lns=[] # 用于存储绘图句柄以合并图例的list |
| | # 创建画布并设置大小 |
| | fig=plt.figure() |
| | fig.set\_size\_inches(width/2.54, height/2.54) # 因为画布输入大小为厘米,此处需转换为英寸,所以除以2.54 |
| | # 通过 add\_subplot 方式创建两个坐标轴,相当于在同一个子图上叠加了两对坐标系 |
| | ax=fig.add\_subplot(111, label="1") |
| | ax2=fig.add\_subplot(111, label="2", frame\_on=False) |
| | # 绘制图1并将绘图句柄返回,以便添加合并图例 |
| | lns1=ax.plot(x,y,color=c1,label=c1) |
| | lns=lns1 |
| | lns2=ax2.plot(x2,y2, color=c2,label=c2) |
| | lns+=lns2 |
| | """图形美化""" |
| | # 调整第二对坐标轴的label和tick位置,以实现双X轴双Y轴效果 |
| | ax2.xaxis.tick\_top() |
| | ax2.yaxis.tick\_right() |
| | ax2.xaxis.set\_label\_position('top') |
| | ax2.yaxis.set\_label\_position('right') |
| | # 设置坐标轴标注 |
| | ax.set\_xlabel("X1", color=c1,fontsize=fontsize) |
| | ax.set\_ylabel("Y1", color=c1,fontsize=fontsize) |
| | ax2.set\_xlabel('X2', color=c2,fontsize=fontsize) |
| | ax2.set\_ylabel('Y2', color=c2,fontsize=fontsize) |
| | # 设置图表标题 |
| | fig.suptitle("Title",fontsize=fontsize+2) |
| | # 设置坐标轴刻度颜色 |
| | ax.tick\_params(axis='x', colors=c1) |
| | ax.tick\_params(axis='y', colors=c1) |
| | ax2.tick\_params(axis='x', colors=c2) |
| | ax2.tick\_params(axis='y', colors=c2) |
| | # 设置坐标轴线颜色 |
| | ax.spines["left"].set\_color("r") # 修改左侧颜色 |
| | ax.spines["right"].set\_color("b") # 修改右侧颜色 |
| | ax.spines["top"].set\_color("b") # 修改上边颜色 |
| | ax.spines["bottom"].set\_color("r") # 修改下边颜色 |
| | # 添加图例 |
| | labs = [l.get\_label() for l in lns] |
| | ax.legend(lns, labs, loc=0,fontsize=fontsize) |
| | plt.tight\_layout() |
| | plt.show() |
| | """ |
| | 使用plt,通过 axes.twinx().twiny() 方式实现双X轴双Y轴图形绘制。 |
| | 问题在于对于第二个Y轴的各种设置无效,label可以通过手动添加的方式创建并指定颜色,而tick颜色则无法修改 |
| | """ |
| | import matplotlib.pyplot as plt |
| | import numpy as np |
| | |
| | """生成数据并设置绘图参数""" |
| | x = np.arange(1, 12, 4) |
| | y = np.arange(1, 4, 1) |
| | x2=x*10 |
| | y2=y**2 |
| | # 设置两种绘图颜色 |
| | c1='r' |
| | c2='b' |
| | # 设置字体大小 |
| | fontsize=12 |
| | # 设置刻度线在坐标轴内 |
| | plt.rcParams['xtick.direction'] = 'in' |
| | plt.rcParams['ytick.direction'] = 'in' |
| | """绘图""" |
| | lns=[] # 用于存储绘图句柄以合并图例的list |
| | # 创建画布 |
| | fig,axes=plt.subplots() |
| | fig.set\_size\_inches(10, 8) |
| | # 绘制图1并将绘图句柄返回,以便添加合并图例 |
| | lns1=axes.plot(x,y,color=c1,label=c1) |
| | lns=lns1 |
| | # 创建双x轴双y轴 |
| | twin\_axes=axes.twinx().twiny() # 使用画布的初始坐标轴对象创建第二对坐标轴,类似于在双x轴的基础上叠加双y轴 |
| | # 绘制图2并将绘图句柄返回,以便添加合并图例 |
| | lns2=twin\_axes.plot(x2,y2,color=c2,label=c2) |
| | lns+=lns2 |
| | """图形美化""" |
| | # 设置坐标轴标注 |
| | axes.set\_xlabel("X1",color=c1, fontsize=fontsize) |
| | axes.set\_ylabel("Y1",color=c1, fontsize=fontsize) |
| | twin\_axes.set\_xlabel("X2",color=c2, fontsize=fontsize) |
| | twin\_axes.set\_ylabel("Y2",color=c2, fontsize=fontsize) # 第二个y轴设置标注无效 |
| | # 设置图表标题 |
| | fig.suptitle("Title",fontsize=fontsize+2) |
| | # 设置第二个y轴的label;由于set\_ylabel无效,因此只能通过该种方式手动添加 |
| | loc\_text\_x=np.min(plt.xlim())+np.ptp(plt.xlim())*1.03 |
| | loc\_text\_y=np.min(plt.ylim())+np.ptp(plt.ylim())*0.5 |
| | str\_text='Y2' |
| | twin\_axes.text(loc\_text\_x, loc\_text\_y, str\_text,rotation=90,color=c2,fontsize=fontsize) |
| | # 设置坐标轴刻度颜色 |
| | axes.tick\_params('x', colors=c1) |
| | axes.tick\_params('y', colors=c1) |
| | twin\_axes.tick\_params('x', colors=c2) |
| | twin\_axes.tick\_params('y', colors=c2) |
| | # 设置坐标轴线颜色 |
| | twin\_axes.spines["left"].set\_color("r") # 修改左侧颜色 |
| | twin\_axes.spines["right"].set\_color("b") # 修改右侧颜色;同第二个y轴的label设置一样,该设置也不起作用 |
| | twin\_axes.spines["top"].set\_color("b") # 修改上边颜色 |
| | twin\_axes.spines["bottom"].set\_color("r") # 修改下边颜色 |
| | # 添加图例 |
| | # lns = lns1+lns2 |
| | labs = [l.get\_label() for l in lns] |
| | axes.legend(lns, labs, loc=0,fontsize=fontsize) |
| | plt.tight\_layout() |
| | plt.show() |
本文参考: