3

Python实现双X轴双Y轴绘图 - geoli91

 2 years ago
source link: https://www.cnblogs.com/geoli91/p/16166200.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

诈尸人口回归。这一年忙着灌水忙到头都掉了,最近在女朋友的提醒下终于想起来博客的账号密码,正好今天灌水的时候需要画一个双X轴双Y轴的图,研究了两小时终于用Py实现了。找资料的过程中没有发现有系统的文章,反正代码都整理出来了,我决定顺势水一篇。

目前找到的plt实现双X轴双Y轴绘图方式有两种:

  1. 使用fig.add_subplot方式将两对坐标系叠加在一个fig上实现双X轴双Y轴效果。所有调整均可完美实现,推荐该方式
  2. 通过axes.twinx().twiny()方式实现双X轴双Y轴图形绘制。问题在于对于第二个Y轴的各种设置无效,label可以通过手动添加的方式创建并指定颜色,而tick颜色则无法修改。可能需要等待官方修复,或者尝试先使用 ax1=axes.twinx()方式,从ax1中获取第二个Y轴,然后再使用ax2.twiny()创建第二个X轴。

fig.add_subplot 方式实现双X轴双Y轴绘图

"""使用plt,通过fig.add_subplot方式将两对坐标系叠加在一个fig上实现双X轴双Y轴效果。所有调整均可完美实现,推荐该方式"""import matplotlib.pyplot as pltimport numpy as np """生成数据并设置绘图参数"""x = np.arange(1, 12, 4)y = np.arange(1, 4, 1)x2=x*10y2=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=lns1lns2=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()

aa

使用 axes.twinx().twiny() 方式实现双X轴双Y轴绘图

"""使用plt,通过 axes.twinx().twiny() 方式实现双X轴双Y轴图形绘制。问题在于对于第二个Y轴的各种设置无效,label可以通过手动添加的方式创建并指定颜色,而tick颜色则无法修改"""import matplotlib.pyplot as pltimport numpy as np """生成数据并设置绘图参数"""x = np.arange(1, 12, 4)y = np.arange(1, 4, 1)x2=x*10y2=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.03loc_text_y=np.min(plt.ylim())+np.ptp(plt.ylim())*0.5str_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+lns2labs = [l.get_label() for l in lns]axes.legend(lns, labs, loc=0,fontsize=fontsize)plt.tight_layout()plt.show()

output

本文参考:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK