matplotlib缩放y轴
我使用matplotlib在一个绘图中显示多个数据集。我希望次要数据有多个“外部”y轴,并且希望这些轴具有相同的范围,但缩放比主绘图轴的范围短 我正在使用twinx()创建附加的y轴,如中所述 MCV示例matplotlib缩放y轴,matplotlib,plot,Matplotlib,Plot,我使用matplotlib在一个绘图中显示多个数据集。我希望次要数据有多个“外部”y轴,并且希望这些轴具有相同的范围,但缩放比主绘图轴的范围短 我正在使用twinx()创建附加的y轴,如中所述 MCV示例 这项工作的关键是操纵每个轴的Bbox。这个解决方案建立在 mpl=matplotlib,np=numpy,pd=pandas 创建主轴,ax 使用ax.Get_position()获取轴的坐标,然后使用Get_points()获取边界点axpos 使用创建辅助轴ax2 使用mpl.tran
这项工作的关键是操纵每个轴的Bbox。这个解决方案建立在 mpl=matplotlib,np=numpy,pd=pandas
ax
ax.Get_position()
获取轴的坐标,然后使用Get_points()
获取边界点axpos
mpl.transforms.Bbox(np.copy(axpos))
为ax2
、ax2pos
创建Bbox。确保创建原始Bbox点的副本,否则两者都将被修改x1
属性或垂直缩放的y1
属性来实现。(例如,ax2pos.y1=0.5*ax2pos.y1
)ax2关闭顶部(或右侧,用于水平缩放)。spines['top']。设置为可见(False)
- 使用
切换每个轴,以避免在以前的层上绘制ax.patch.set_visible()
- 使用ax.set_zorder()调整轴的绘图顺序
- 由于缩放,您可能必须调整保存图形时使用的边界框。这可以通过创建另一个Bbox并将其作为
参数传递给来实现Bbox\u inches
ax.twinx()
不再提供对第二个轴的控制,因此必须手动将其添加到图形中
mpl=matplotlib,plt=matplotlib.pyplot,np=numpy,pd=pandas
plt.subplot()创建主图形fig
和轴ax
ax2a
,ax2a.twinx()
您还需要考虑使用两个轴的主轴和次轴的X轴对齐。 MCV解决方案
你能创建一个MCV吗?我已经添加了一个MCV。如果还有什么我能帮忙的,请告诉我。
ax = day6Si.plot(
'time', 'pce_rolling'
)
dataPsc[ dataPsc.day == 5 ].plot(
'time', 'pce_rolling', ax = ax
)
ax3 = ax.twinx()
ax3.fill_between(
day6Si.time, 0, day6Si.temperature
)
rspine = ax3.spines[ 'right' ]
rspine.set_position( ( 'axes', 1.15 ) )
ax3.set_frame_on( True )
ax3.patch.set_visible( False )
ax3.set_ylim( bottom = 0 )
ax2 = ax.twinx()
ax2.fill_between(
day6Si.time, 0, day6Si.intensity
)
rspine = ax2.spines[ 'right' ]
rspine.set_position( ( 'axes', 1.05 ) )
ax2.set_frame_on( True )
ax2.patch.set_visible( False )
ax2.set_ylim( bottom = 0 )
td = np.linspace( 0, np.pi, 101 )
df = pd.DataFrame( data = {
'main': np.sin( td ),
'secondary': 10 * np.sin( td )
} )
ax = df.plot( df.index.values, 'main' )
ax2 = ax.twinx()
ax2.fill_between(
df.index.values, 0, df.secondary,
facecolor = '#a05050',
label = 'Secondary'
)
rspine = ax2.spines[ 'right' ]
rspine.set_position( ( 'axes', 1.05 ) )
ax2.set_frame_on( True )
ax2.patch.set_visible( False )
ax2.set_ylim( bottom = 0 )
ax2.set_ylabel( 'Secondary' )
ax.set_ylim( 0, 1 )
ax.legend( [ 'Main', 'Secondary' ] )
td = np.linspace( 0, np.pi, 101 )
df = pd.DataFrame( data = {
'main': np.sin( td ),
'secondary': 10 * np.sin( td )
} )
ax = df.plot( df.index.values, 'main' )
axpos = ax.get_position()
ax2 = ax.twinx()
ax2pos = mpl.transforms.Bbox( np.copy( axpos.get_points() ) ) # clone bounding box
ax2pos.y1 = ax2pos.y1 * 0.5 # scale y axis
ax2.set_position( ax2pos ) # set bounding box
ax2.fill_between(
df.index.values, 0, df.secondary,
facecolor = '#a05050',
label = 'Secondary'
)
ax2.spines[ 'right' ].set_position( ( 'axes', 1.05 ) )
ax2.spines[ 'top' ].set_visible( False )
ax2.set_frame_on( True )
ax2.patch.set_visible( False )
ax2.set_ylim( bottom = 0 )
ax2.set_ylabel( 'Secondary' )
ax.set_ylim( 0, 1 )
ax.legend( [ 'Main', 'Secondary' ] )
ax = day6Si.plot(
'time', 'pce_rolling', kind = 'line', label = 'Si',
zorder = 40
)
dataPsc[ dataPsc.day == 5 ].plot(
'time', 'pce_rolling', kind = 'line', label = 'PSC',
zorder = 30, ax = ax
)
axpos = ax.get_position()
ax.set_zorder( 30 )
ax.patch.set_visible( False )
ax.set_xlim( 124.5, 141.5 )
ax.set_ylim( 10, 20 )
ax.set_ylabel( 'PCE (%)' )
ax.set_xlabel( 'Time' )
ax.set_xticklabels( [ '4', '6', '8', '10', '12', '14', '16', '18', '20' ] )
ax.legend( loc = 'upper right', bbox_to_anchor = ( 1, 1 ) )
# temperature
ax3 = ax.twinx()
ax3.fill_between(
day6Si.time, 0, day6Si.temperature,
facecolor = '#f0c5b5',
label = 'Temperature (Rel)'
)
ax3pos = mpl.transforms.Bbox( np.copy( axpos.get_points() ) ) # clone bounding box
ax3pos.y1 = ax3pos.y1 * 0.5 # scale y axis
ax3.set_position( ax3pos ) # set bounding box
ax3.set_zorder( 10 )
ax3.spines[ 'right' ].set_position( ( 'axes', 1.025 ) ) # shift y axis
ax3.set_frame_on( True )
ax3.spines[ 'top' ].set_visible( False ) # remove top frame line
ax3.patch.set_visible( True )
ax3.set_ylim( bottom = 0, top = 60 )
ax3.set_ylabel( 'Temperature (C)' )
# intensity
ax2 = ax.twinx()
ax2.fill_between(
day6Si.time, 0, day6Si.intensity,
facecolor = '#dddd99',
label = 'Intensity (Rel)'
)
ax2pos = mpl.transforms.Bbox( np.copy( axpos.get_points() ) ) # clone bounding box
ax2pos.y1 = ax2pos.y1 * 0.33 # scale y axis
ax2.set_position( ax2pos ) # set bounding box
ax2.set_zorder( 20 )
ax2.spines[ 'right' ].set_position( ( 'axes', 1.125 ) ) # shift y asix
ax2.set_frame_on( True )
ax2.spines[ 'top' ].set_visible( False ) # remove top frame
ax2.patch.set_visible( False )
ax2.set_ylim( bottom = 0, top = 1 )
ax2.set_ylabel( 'Intensity (suns)' )
savebox = mpl.transforms.Bbox( [ [ 0, 0 ], [ 10* 1.15, 8 ] ] ) # bounding box in inches for saving
plt.gcf().savefig( figloc + '/day6.svg', format = 'svg', bbox_inches = savebox )
td = np.linspace( 0, np.pi, 101 )
df = pd.DataFrame( data = {
'main': np.sin( td ),
'secondary': 10 * np.sin( td )
} )
fig, ax = plt.subplots()
df.plot( df.index.values, 'main', ax = ax )
axpos = ax.get_position()
ax2pos = mpl.transforms.Bbox( np.copy( axpos.get_points() ) )
ax2pos.y1 = ax2pos.y1 * 0.5 # scale y axis
ax2a = fig.add_axes( ax2pos ) # create secondary axes
ax2 = ax2a.twinx() # create right y-axis
ax2.fill_between(
df.index.values, 0, df.secondary,
facecolor = '#a05050',
label = 'Secondary'
)
ax2.spines[ 'right' ].set_position( ( 'axes', 1.05 ) )
ax2.spines[ 'top' ].set_visible( False )
ax2.set_frame_on( True )
ax2.patch.set_visible( False )
ax2.set_ylim( bottom = 0 )
ax2.set_ylabel( 'Secondary' )
# clean up secondary axes tick marks and labels
ax2a.tick_params( left = False, bottom = False )
ax2.tick_params( left = False, bottom = False )
ax2a.set_xticklabels( [] )
ax2a.set_yticklabels( [] )
ax.set_ylim( 0, 1 )
ax.legend( [ 'Main', 'Secondary' ] )