Matplotlib 中 x 轴和 y 轴的玩法大全:从基础到高级技巧
Matplotlib 的坐标轴系统是其强大功能的核心,提供了丰富的定制选项。本文将全面总结 x 轴和 y 轴的各种玩法,并详细比较子图级别与整图级别的设置差异。
一、x 轴和 y 轴的基础玩法
(一)轴的范围和刻度控制
import matplotlib. pyplot as plt
import numpy as np
plt. xlim( 0 , 10 )
plt. ylim( - 5 , 5 )
ax. set_xlim( 0 , 10 )
ax. set_ylim( - 5 , 5 )
ax. autoscale( enable= True , axis= 'x' , tight= True )
plt. xticks( [ 0 , 2 , 4 , 6 , 8 , 10 ] )
plt. yticks( np. arange( - 5 , 6 , 1 ) )
plt. xticks( [ 0 , 5 , 10 ] , [ 'Start' , 'Middle' , 'End' ] )
from matplotlib. ticker import MultipleLocator
ax. xaxis. set_major_locator( MultipleLocator( 2 ) )
ax. xaxis. set_minor_locator( MultipleLocator( 0.5 ) )
(二)轴标签和标题
plt. xlabel( 'X Axis Label' , fontsize= 12 , color= 'blue' )
plt. ylabel( 'Y Axis Label' , fontsize= 12 , color= 'red' )
ax. set_xlabel( 'X Axis Label' , fontdict= { 'fontsize' : 12 , 'fontweight' : 'bold' } )
ax. set_ylabel( 'Y Axis Label' , fontdict= { 'fontsize' : 12 , 'fontweight' : 'bold' } )
plt. xticks( rotation= 45 )
(三)轴刻度格式化和样式
from matplotlib. ticker import ScalarFormatter
ax. yaxis. set_major_formatter( ScalarFormatter( useMathText= True ) )
from matplotlib. ticker import PercentFormatter
ax. yaxis. set_major_formatter( PercentFormatter( 1.0 ) )
import matplotlib. dates as mdates
ax. xaxis. set_major_formatter( mdates. DateFormatter( '%Y-%m-%d' ) )
ax. set_xscale( 'log' )
ax. set_yscale( 'log' )
ax. set_yscale( 'symlog' , linthresh= 0.01 )
(四)轴线和刻度样式
ax. spines[ 'bottom' ] . set_color( 'blue' )
ax. spines[ 'bottom' ] . set_linewidth( 2 )
ax. spines[ 'left' ] . set_color( 'red' )
ax. spines[ 'left' ] . set_linewidth( 2 )
ax. spines[ 'top' ] . set_visible( False )
ax. spines[ 'right' ] . set_visible( False )
ax. tick_params( axis= 'x' , direction= 'out' , length= 6 , width= 2 , color= 'blue' )
ax. tick_params( axis= 'y' , direction= 'in' , length= 10 , width= 1 , color= 'red' )
ax. tick_params( axis= 'x' , labelsize= 10 , labelcolor= 'green' )
二、高级轴玩法
(一)双轴和共享轴
ax2 = ax. twinx( )
ax2. plot( x, y2, 'r-' )
ax2. set_ylabel( 'Second Y Axis' )
ax3 = ax. twiny( )
ax3. plot( x2, y, 'g-' )
ax3. set_xlabel( 'Second X Axis' )
fig, ( ax1, ax2) = plt. subplots( 2 , 1 , sharex= True )
fig, ( ax1, ax2) = plt. subplots( 1 , 2 , sharey= True )
(二)轴位置和方向
ax. spines[ 'bottom' ] . set_position( ( 'data' , 0 ) )
ax. spines[ 'left' ] . set_position( ( 'data' , 0 ) )
ax. invert_xaxis( )
ax. invert_yaxis( )
ax. spines[ 'left' ] . set_position( 'zero' )
ax. spines[ 'bottom' ] . set_position( 'zero' )
(三)自定义刻度和网格
def custom_formatter ( x, pos) :
if x >= 1000 :
return f' { x/ 1000 : .0f } k'
else :
return f' { x: .0f } '
ax. xaxis. set_major_formatter( plt. FuncFormatter( custom_formatter) )
ax. grid( True , which= 'major' , linestyle= '-' , linewidth= 0.5 , color= 'gray' , alpha= 0.5 )
ax. grid( True , which= 'minor' , linestyle= ':' , linewidth= 0.5 , color= 'lightgray' , alpha= 0.3 )
ax. xaxis. grid( True , which= 'major' )
ax. yaxis. grid( True , which= 'minor' )
(四)轴限制和自动缩放
margin = 0.1
x_margin = ( x_max - x_min) * margin
y_margin = ( y_max - y_min) * margin
ax. set_xlim( x_min - x_margin, x_max + x_margin)
ax. set_ylim( y_min - y_margin, y_max + y_margin)
ax. set_aspect( 'equal' )
ax. set_aspect( 2 )
ax. set_autoscale_on( True )
ax. set_ylim( bottom= 0 )
三、子图与整幅图的轴设置差异
(一)设置级别的差异
设置类型 子图级别 (Axes) 整图级别 (Figure) 轴范围 ax.set_xlim(), ax.set_ylim()无直接设置,但可通过布局调整影响 轴标签 ax.set_xlabel(), ax.set_ylabel()fig.supxlabel(), fig.supylabel() (Matplotlib 3.4+)轴刻度 ax.set_xticks(), ax.set_yticks()无直接设置 刻度标签 ax.set_xticklabels(), ax.set_yticklabels()无直接设置 轴标题 ax.set_title()fig.suptitle()共享轴 ax.sharex(), ax.sharey()创建子图时通过 sharex, sharey 参数
(二)实际应用中的区别
fig, axes = plt. subplots( 2 , 2 , figsize= ( 10 , 8 ) )
axes[ 0 , 0 ] . set_xlim( 0 , 10 )
axes[ 0 , 0 ] . set_xlabel( 'X for subplot 1' )
fig. suptitle( 'Overall Figure Title' )
fig. supxlabel( 'Common X Label' )
fig. supylabel( 'Common Y Label' )
for ax in axes. flat:
ax. set_xlim( 0 , 10 )
ax. tick_params( axis= 'x' , rotation= 45 )
fig, axes = plt. subplots( 2 , 2 , sharex= True , sharey= True )
axes[ 0 , 0 ] . sharex( axes[ 1 , 0 ] )
(三)布局调整的影响
plt. subplots_adjust(
left= 0.1 ,
bottom= 0.1 ,
right= 0.9 ,
top= 0.9 ,
wspace= 0.2 ,
hspace= 0.3
)
fig, axes = plt. subplots( 2 , 2 , constrained_layout= True )
import matplotlib. gridspec as gridspec
gs = gridspec. GridSpec( 2 , 2 , width_ratios= [ 1 , 2 ] , height_ratios= [ 2 , 1 ] )
ax1 = fig. add_subplot( gs[ 0 , 0 ] )
ax2 = fig. add_subplot( gs[ 0 , 1 ] )
ax3 = fig. add_subplot( gs[ 1 , : ] )
四、实用技巧和最佳实践
(一)处理日期轴
import pandas as pd
import matplotlib. dates as mdates
dates = pd. date_range( '2023-01-01' , '2023-12-31' , freq= 'D' )
values = np. random. randn( len ( dates) ) . cumsum( )
fig, ax = plt. subplots( )
ax. plot( dates, values)
ax. xaxis. set_major_formatter( mdates. DateFormatter( '%Y-%m' ) )
ax. xaxis. set_major_locator( mdates. MonthLocator( ) )
plt. xticks( rotation= 45 )
(二)处理分类数据轴
categories = [ 'A' , 'B' , 'C' , 'D' , 'E' ]
values = [ 23 , 45 , 56 , 12 , 78 ]
fig, ax = plt. subplots( )
ax. bar( categories, values)
ax. set_xticks( range ( len ( categories) ) )
ax. set_xticklabels( [ f'Category { c} ' for c in categories] , rotation= 45 )
(三)高级轴装饰
ax. spines[ 'bottom' ] . set_position( 'zero' )
ax. spines[ 'left' ] . set_position( 'zero' )
ax. spines[ 'top' ] . set_visible( False )
ax. spines[ 'right' ] . set_visible( False )
ax. plot( 1 , 0 , ">k" , transform= ax. get_yaxis_transform( ) , clip_on= False )
ax. plot( 0 , 1 , "^k" , transform= ax. get_xaxis_transform( ) , clip_on= False )
ax. axhspan( ymin= 0 , ymax= 1 , facecolor= 'green' , alpha= 0.1 )
ax. axvspan( xmin= 0 , xmax= 1 , facecolor= 'blue' , alpha= 0.1 )
(四)响应式轴调整
fig, ax = plt. subplots( )
ax. plot( x, y)
fig. autofmt_xdate( )
def update_ticks ( ax, fig) :
width = fig. get_figwidth( ) * fig. dpi
height = fig. get_figheight( ) * fig. dpi
x_ticks = max ( 5 , int ( width / 100 ) )
y_ticks = max ( 5 , int ( height / 80 ) )
ax. xaxis. set_major_locator( plt. MaxNLocator( x_ticks) )
ax. yaxis. set_major_locator( plt. MaxNLocator( y_ticks) )
fig. canvas. mpl_connect( 'resize_event' , lambda event: update_ticks( ax, fig) )
五、总结表格:子图与整图轴设置对比
功能 子图级别 (Axes) 整图级别 (Figure) 说明 轴范围 set_xlim(), set_ylim()无直接方法 整图可通过布局调整间接影响 轴标签 set_xlabel(), set_ylabel()supxlabel(), supylabel()整图方法需要 Matplotlib 3.4+ 轴标题 set_title()suptitle()整图标题显示在所有子图上方 刻度位置 set_xticks(), set_yticks()无直接方法 刻度标签 set_xticklabels(), set_yticklabels()无直接方法 刻度格式 xaxis.set_major_formatter() 等无直接方法 共享轴 sharex(), sharey()创建时通过参数设置 整图级别设置更简洁 轴线样式 spines[] 相关方法无直接方法 网格线 grid()无直接方法 布局调整 无 subplots_adjust(), tight_layout()整图级别控制所有子图位置