matshow组合矩阵与向量绘图时y轴范围异常问题求助
Let's break down why you're seeing that weird y-axis range on your matrix plot, and how to fix it while keeping the x-axis aligned between the two plots.
The Root Cause
When you use sharex=True with matshow, you run into a conflict because:
matshowdefaults toorigin='upper', which reverses the y-axis (so row 0 sits at the top, row 9 at the bottom).- Your vector subplot (axes[1]) only has 1 row, so its y-axis range is
-0.5to0.5. When sharing the x-axis, matplotlib tries to sync axis properties in unexpected ways, which messes up the matrix's y-axis bounds. Manually settingset_ylimdoesn't work here because the shared axis locks some properties.
Solution 1: Align X-Axes Without sharex=True
Instead of relying on sharex, manually sync the x-axis ranges and ticks between the two subplots. This gives you full control over both axes.
Here's the modified code:
import numpy as np import matplotlib.pyplot as plt vec_data = np.array([[ 0., 1., 1., 1., 0., 1., 1., 0., 0., 0.]]) mat_data = np.array([ [ 0. , 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 1. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0.5, 0. , 0.5, 0. , 0. , 0. , 0. ], [ 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1, 0.1, 0. , 0.1], [ 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0. ], [ 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1, 0.1, 0.1, 0. ]]) # Remove sharex=True fig, axes = plt.subplots(2,1,figsize=(4,4),sharey=False,gridspec_kw = {'height_ratios':[25,1]}) # Plot matrix axes[0].matshow(mat_data) # Plot vector axes[1].matshow(vec_data) # Sync x-axis ranges: matshow uses [-0.5, n_cols-0.5] for x bounds x_min, x_max = -0.5, mat_data.shape[1] - 0.5 axes[0].set_xlim(x_min, x_max) axes[1].set_xlim(x_min, x_max) # Sync x-axis ticks (optional but makes alignment clearer) axes[0].set_xticks(range(mat_data.shape[1])) axes[1].set_xticks(range(mat_data.shape[1])) # Your existing formatting for the vector subplot axes[1].tick_params(direction='out', length=6, width=0) axes[1].set_yticklabels(['']) axes[1].set_xlabel('vector') plt.tight_layout() plt.show()
Solution 2: Fix Y-Axis Range With sharex=True
If you want to keep sharex=True, you need to explicitly set the y-axis range for the matrix subplot after plotting, and ensure the y-axis origin is correctly set (since matshow uses origin='upper' by default).
Here's how:
import numpy as np import matplotlib.pyplot as plt vec_data = np.array([[ 0., 1., 1., 1., 0., 1., 1., 0., 0., 0.]]) mat_data = np.array([ [ 0. , 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 1. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0.5, 0. , 0.5, 0. , 0. , 0. , 0. ], [ 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1, 0.1, 0. , 0.1], [ 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0. ], [ 0.1, 0.1, 0.1, 0.1, 0. , 0.1, 0.1, 0.1, 0.1, 0. ]]) fig, axes = plt.subplots(2,1,figsize=(4,4),sharey=False,sharex=True,gridspec_kw = {'height_ratios':[25,1]}) axes[0].matshow(mat_data) axes[1].matshow(vec_data) # Fix the matrix's y-axis range: matshow uses origin='upper', so y goes from 9 (bottom) to 0 (top) axes[0].set_ylim(mat_data.shape[0]-0.5, -0.5) # Your existing formatting axes[1].tick_params(direction='out', length=6, width=0) axes[1].set_yticklabels(['']) axes[1].set_xlabel('vector') plt.tight_layout() plt.show()
The key here is that matshow with origin='upper' has a reversed y-axis, so we set ylim from 9.5 (bottom) to -0.5 (top) instead of the other way around. This overrides the incorrect range caused by sharex=True.
Either solution will fix your y-axis issue while keeping the x-axes perfectly aligned between the matrix and vector plots.
内容的提问来源于stack exchange,提问作者user3821012

