Skip to main content
 首页 » 编程设计

python之get_position() 在使用颜色条时会做一些奇怪的事情

2025年05月04日9bonelee

我有一个数据矩阵,其中 x 轴和 y 轴是对数的。我正在尝试使用 imshow 来显示矩阵,但是因为我想要对数轴,所以我将 imshow 轴中的刻度设置为 [],然后覆盖另一组轴:

import matplotlib.pyplot as plt 
import numpy as np 
 
# the x,y max and min are the log values 
array = np.zeros((2,2)) 
array[1,1] = -1 
fig = plt.figure() 
ax = plt.imshow( 
    array,  
    extent = (0,1, 1, 0),  
    interpolation = 'nearest').get_axes() 
ax.invert_yaxis() 
 
# add a colorbar 
# cb = plt.colorbar()      # <----- THIS CAUSES TROUBLE 
# cb.set_label('zbar') 
 
ax.set_aspect(1) 
ax.xaxis.set_ticks([]) 
ax.yaxis.set_ticks([]) 
position = ax.get_position() 
aspect = ax.get_aspect() 
 
# overlay another set of axes  
ax_log = fig.add_subplot(111, frameon = False) 
ax_log.set_xscale('log') 
ax_log.set_yscale('log') 
ax_log.axis((10**0, 10**1, 10**0, 10**1)) # old min and max but exponentiated   
ax_log.set_position(position) 
ax_log.set_aspect(aspect) 
 
plt.savefig('test.png', bbox_inches = 'tight') 
plt.close() 

没有颜色条这工作正常:

但是当我取消注释添加颜色条的行时,我得到了一个奇怪的转变:

看起来颜色条以某种方式将图像稍微向左移动,但考虑到我在创建颜色条后调用 get_position() 这看起来很奇怪。我是否忽略了制作此情节的更简单方法?有一些简单的解决方法吗?

请您参考如下方法:

四处搜索了一下,我找到了一个解决方法,也许还有更好的...

问题似乎是 plt.colorbar() 会从其绘制的绘图中“窃取”空间。它仍然有点奇怪,因为我仍然期望 get_position() 返回正确的坐标。但作为一种解决方法,我使用了 GridSpec 和原始的 Colorbar 构造函数。

import matplotlib.pyplot as plt 
import numpy as np 
from matplotlib.gridspec import GridSpec 
from matplotlib.colorbar import Colorbar 
 
# the x,y max and min are the log values 
array = np.zeros((2,2)) 
array[1,1] = -1 
fig = plt.figure() 
gs = GridSpec(10,11)            # create a 10 x 11 grid 
ax = plt.subplot(gs[:,0:-1])    # make subplot on 10 x 10 part  
im = plt.imshow( 
    array,  
    extent = (0,1, 1, 0),  
    interpolation = 'nearest',  
    axes = ax) 
ax.invert_yaxis() 
 
# add a colorbar 
cb_ax = plt.subplot(gs[:,-1])   # put the colorbar on the last column 
cb = Colorbar(ax = cb_ax, mappable = im ) # use the raw colorbar constructor 
cb.set_label('zbar') 
 
ax.set_aspect(1) 
ax.xaxis.set_ticks([]) 
ax.yaxis.set_ticks([]) 
position = ax.get_position() 
aspect = ax.get_aspect() 
 
# overlay another set of axes  
ax_log = fig.add_subplot(111, frameon = False) # can't use gridspec? 
ax_log.set_xscale('log') 
ax_log.set_yscale('log') 
ax_log.axis((10**0, 10**1, 10**0, 10**1)) # old min and max but exponentiated   
ax_log.set_position(position) 
ax_log.set_aspect(aspect) 
 
plt.savefig('test.pdf', bbox_inches = 'tight') 
plt.close() 

同样很奇怪的是我不能使用 GridSpec 对象来初始化第二组轴(这样做会使图像消失)。