詐屍人口迴歸。這一年忙著灌水忙到頭都掉了,最近在女朋友的提醒下終於想起來部落格的賬號密碼,正好今天灌水的時候需要畫一個雙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軸。
fig.add_subplot 方式實現雙X軸雙Y軸繪圖
"""
使用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()
使用 axes.twinx().twiny() 方式實現雙X軸雙Y軸繪圖
"""
使用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()
本文參考: