Matplotlib:如何强制整数刻度标签?

gha*_*gha 40 python plot matplotlib

我的python脚本使用matplotlib绘制x,y,z数据集的2D"热图".我的x和y值代表蛋白质中的氨基酸残基,因此只能是整数.当我放大绘图时,它看起来像这样:

带有浮动刻度线的2D热图

正如我所说,xy轴上的浮点值对我的数据没有意义,因此我希望它看起来像这样: 在此输入图像描述

任何想法如何实现这一目标?这是生成图的代码:

def plotDistanceMap(self):
    # Read on x,y,z
    x = self.currentGraph['xData']
    y = self.currentGraph['yData']
    X, Y = numpy.meshgrid(x, y)
    Z = self.currentGraph['zData']
    # Define colormap
    cmap = colors.ListedColormap(['blue', 'green', 'orange', 'red'])
    cmap.set_under('white')
    cmap.set_over('white')
    bounds = [1,15,50,80,100]
    norm = colors.BoundaryNorm(bounds, cmap.N)
    # Draw surface plot
    img = self.axes.pcolor(X, Y, Z, cmap=cmap, norm=norm)
    self.axes.set_xlim(x.min(), x.max())
    self.axes.set_ylim(y.min(), y.max())
    self.axes.set_xlabel(self.currentGraph['xTitle'])
    self.axes.set_ylabel(self.currentGraph['yTitle'])
    # Cosmetics
    #matplotlib.rcParams.update({'font.size': 12})
    xminorLocator = MultipleLocator(10)
    yminorLocator = MultipleLocator(10)
    self.axes.xaxis.set_minor_locator(xminorLocator)
    self.axes.yaxis.set_minor_locator(yminorLocator)
    self.axes.tick_params(direction='out', length=6, width=1)
    self.axes.tick_params(which='minor', direction='out', length=3, width=1)
    self.axes.xaxis.labelpad = 15
    self.axes.yaxis.labelpad = 15
    # Draw colorbar
    colorbar = self.figure.colorbar(img, boundaries = [0,1,15,50,80,100], 
                                    spacing = 'proportional',
                                    ticks = [15,50,80,100], 
                                    extend = 'both')
    colorbar.ax.set_xlabel('Angstrom')
    colorbar.ax.xaxis.set_label_position('top')
    colorbar.ax.xaxis.labelpad = 20
    self.figure.tight_layout()      
    self.canvas.draw()
Run Code Online (Sandbox Code Playgroud)

Céd*_*pay 76

这应该更简单:

(来自https://scivision.co/matplotlib-force-integer-labeling-of-axis/)

import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
#...
ax = plt.figure().gca()
#...
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
Run Code Online (Sandbox Code Playgroud)

  • +1 代表你的答案,但 -1 代表糟糕的 API!`plt.axes().xaxis.set_major_locator(MaxNLocator(integer=True))` 为我工作。 (8认同)
  • 这给我带来了非常奇怪的结果。它将刻度线[0,2,4,8,10]变成[0.0,1.5,3.0,4.5,7.5,9.0,10.5]。给定[docs](http://matplotlib.org/api/ticker_api.html#matplotlib.ticker.MaxNLocator)的内容,这应该不会发生。 (3认同)
  • 它不会为我将刻度标签放在给定区域的中间点(如问题的示例图像中所示),并且每一秒(未标记的)刻度都会丢失。有没有一个简单的技巧来实现这些目标?'2' 应该在 2.5 的位置,而不是 2.0。 (2认同)

LBo*_*oss 6

ax.set_xticks([2,3])
ax.set_yticks([2,3])
Run Code Online (Sandbox Code Playgroud)

  • @Andris' [六年前的答案](/sf/answers/2164155381/) 提供了相同的基本建议,但有很多额外的上下文代码。 (2认同)

Mis*_*oob 5

通过简单地将索引转换为字符串,以下解决方案i对我有用:

    import matplotlib.pyplot as plt
    import time

    datay = [1,6,8,4] # Just an example
    datax = []
    
    # In the following for loop datax in the end will have the same size of datay, 
    # can be changed by replacing the range with wathever you need
    for i in range(len(datay)):
        # In the following assignment statement every value in the datax 
        # list will be set as a string, this solves the floating point issue
        datax += [str(1 + i)]

    a = plt

    # The plot function sets the datax content as the x ticks, the datay values
    # are used as the actual values to plot
    a.plot(datax, datay)

    a.show()
Run Code Online (Sandbox Code Playgroud)

  • 将整数列表转换为 str 列表 => `list(map(str, list_int))` (2认同)