将xticks和yticks放在imshow plot

时间:2018-05-07 17:21:50

标签: python matplotlib plot graphics

我正在使用matplotlib绘制带有一些信息的热图,我想将xticks和yticks移动到中心。我已经在stackoverflow中搜索了以前的问题,但我无法找到适合该问题的问题。我附上了我的代码和我得到的图像:

import matplotlib.pyplot as plt
from matplotlib import colors
import numpy as np

def plot():
    intensity= np.random.rand(10,10)

    matrix_intensity=np.matrix(intensity)
    max_intensity=matrix_intensity.max()
    min_intensity = matrix_intensity.min()
    for e in range(len(intensity)):
        for i in range(len(intensity[e])):
            intensity[e][i]=float(intensity[e][i])/float(max_intensity)
    np.random.seed(101)
    cmap = colors.ListedColormap(['white','khaki', 'goldenrod','yellowgreen','mediumseagreen','darkcyan','tomato','indianred' ,'sienna','maroon'])
    bounds = np.linspace(min_intensity/max_intensity,1,11).tolist()
    norm = colors.BoundaryNorm(bounds, cmap.N)

    img = plt.imshow(intensity, interpolation='none', origin='lower',extent=[0,len(intensity),0,len(intensity)],
                     cmap=cmap, norm=norm)

    cb=plt.colorbar(img, fraction=0.1,cmap=cmap, norm=norm, boundaries=bounds,format='%.2f') #'%.2f')
    cb.set_label(label='Ratio',fontsize=12,labelpad=10)
    plt.ylabel('Origin',fontsize=11)
    plt.xlabel('Destination',fontsize=11)
    plt.title('Best route:',fontsize=10)
    plt.suptitle('Best Solution:',fontsize=10)
    plt.xticks(range(1,len(intensity)+1))
    plt.yticks(range(1,len(intensity)+1))
    plt.savefig('images/hello.png')
    plt.show()

事实是,我希望x和y刻度指出每个正方形的中心,否则,绘制正方形是没有意义的。有人知道如何解决这个问题吗?也许这个问题很明显,但有时很难理解所有语句的matplotlib文档。

Image of the problem

3 个答案:

答案 0 :(得分:2)

显而易见的解决方案可能是使用不同的extent,即让图片生效在0.5len(intensity)+0.5之间。

extent=[.5, len(intensity)+.5, .5, len(intensity)+.5]
img = plt.imshow(intensity, interpolation='none', origin='lower',extent=extent,
                     cmap=cmap, norm=norm)

答案 1 :(得分:1)

您需要更改将xticksyticks loclabels设置为以下内容的方式:

plt.xticks([x-0.5 for x in list(range(1,len(intensity)+1))], range(1,len(intensity)+1))
plt.yticks([x-0.5 for x in list(range(1,len(intensity)+1))], range(1,len(intensity)+1))

输出:

enter image description here

答案 2 :(得分:0)

其他答案都很好,但是我想提供一个更通用的实现,它也不会改变默认刻度,因为我有一个函数可用于计算轴限制并将它们设置为@ImportanceOfBeingErnest回答。

import numpy as np  

def span_from_pixels(p,n=None):
    """From positions of pixel centers p returns a range from side to side. Useful to adjust plot extent in imshow.
    In alternative, p can be provided as range and number of pixels.
    Note that np.linspace has flag retsteps to return step size."""

    if n is None:
        n=len(p)

    dx=(np.max(p)-np.min(p))/(n-1)
    return (np.min(p)-dx/2,np.max(p)+dx/2)

def test_span_from_pixels():
    print (span_from_pixels([0,3],4)) #[-0.5,3.5]
    print (span_from_pixels([0,2],3)) #[-0.5,2.5]
    print (span_from_pixels([0,1,2])) #[-0.5,2.5]
    print (span_from_pixels([0,0.5,1,1.5,2])) #[-0.25,2.25]

如果出现问题,请告诉我,这些已在我的代码中进行了测试,但我进行了一些更改以删除依赖项。我假设我没有破坏任何东西,但我现在无法对其进行测试。