8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何强制整数刻度标签

Andreas Tille 1月前

49 0

我的 python 脚本使用 matplotlib 绘制 x、y、z 数据集的 2D“热图”。我的 x 和 y 值表示蛋白质中的氨基酸残基,因此只能是整数。当我放大时...

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

2D heat map with float tick marks

正如我所说的,xy 轴上的浮点值对我的数据没有意义,因此我希望它看起来像这样:enter image description here

有什么想法可以实现这一点吗?这是生成图表的代码:

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()
帖子版权声明 1、本帖标题:如何强制整数刻度标签
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Andreas Tille在本站《matplotlib》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 根据 修改刻度标签 ,我想出了一个解决方案,不知道它是否适用于您的情况,因为您的代码片段本身无法执行。

    这个想法是强制刻度标签为 .5 间距,然后用其整数对应部分替换每 .5 刻度,并将其他刻度替换为空字符串。

    import numpy
    import matplotlib.pyplot as plt
    
    fig, (ax1, ax2) = plt.subplots(1,2)
    
    x1, x2 = 1, 5
    y1, y2 = 3, 7
    
    # first axis: ticks spaced at 0.5
    ax1.plot([x1, x2], [y1, y2])
    ax1.set_xticks(numpy.arange(x1-1, x2+1, 0.5))
    ax1.set_yticks(numpy.arange(y1-1, y2+1, 0.5))
    
    # second axis: tick labels will be replaced
    ax2.plot([x1, x2], [y1, y2])
    ax2.set_xticks(numpy.arange(x1-1, x2+1, 0.5))
    ax2.set_yticks(numpy.arange(y1-1, y2+1, 0.5))
    
    # We need to draw the canvas, otherwise the labels won't be positioned and 
    # won't have values yet.
    fig.canvas.draw()
    
    # new x ticks  '1'->'', '1.5'->'1', '2'->'', '2.5'->'2' etc.
    labels = [item.get_text() for item in ax2.get_xticklabels()]
    new_labels = [ "%d" % int(float(l)) if '.5' in l else '' for l in labels]
    ax2.set_xticklabels(new_labels)
    
    # new y ticks
    labels = [item.get_text() for item in ax2.get_yticklabels()]
    new_labels = [ "%d" % int(float(l)) if '.5' in l else '' for l in labels]
    ax2.set_yticklabels(new_labels)
    
    fig.canvas.draw()
    plt.show()
    

    如果您想要缩小很多,则需要格外小心,因为这会产生一组非常密集的刻度标签。

  • 构造 str 列表:datax = [str(i + 1) for i in range(len(datay))]

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

  • 您好,欢迎来到 SO!datax 对应什么?您没有分享设置刻度标签的代码,因此不清楚 datax 是 x 刻度还是 y 刻度(对应于 datay 变量)的标签列表。例如,如果 OP 的 x 变量范围从 1 到 15,我看不出这将如何工作。我建议您让您的答案适用于任何值范围,就像当前接受的答案一样。由于您是新用户,我暂时不会否决这个答案,但我鼓励您尽快改进它。

  • 只需将索引转换 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()
    
  • 尽管此答案与另一个使用 MaxNLocator 的答案类似,但我发现此答案中的额外上下文是一个很好的增强。谢谢。

  • 另一种选择 MaxNLocator matplotlib.ticker.MultipleLocator 。默认情况下,它只输出整数值。

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.ticker as tck
    
    x = np.linspace(-5, 5, 90)
    y = np.sinc(x)
    
    fig, ax = plt.subplots(figsize=(6, 2), layout='constrained')
    ax.xaxis.set_major_locator(tck.MultipleLocator())
    ax.set_xlabel('x')
    ax.plot(x, y)
    

    enter image description here

    如果您只需要 n 个刻度中的一个,则只需将此数字提供给 MultipleLocator ,例如 MultipleLocator(3)

    enter image description here

    实际上,您可以将基数设置为任何实数,而不仅限于整数。


    相比确保 MaxNLocator , MultipleLocator 具有整数刻度,而使用 则teger=True in MaxNLocator 有一个限制:

    整数 :bool,默认值 False 。如果 True ,则刻度将仅采用整数值, provided at least min_n_ticks integers are found within the view limits .

    因此 MaxNLocator 也可以产生这样的结果:

    enter image description here

  • ax.set_xticks([2,3])
    ax.set_yticks([2,3])
    
  • 引用 10

    如果使用 plt.subplot,您还可以执行以下操作:fig, ax = plt.subplots(figsize =(12, 4)),然后您可以再次使用 ax:ax.yaxis.set_major_locator(MaxNLocator(integer=True))

  • 引用 11

    您的答案为 +1,但糟糕的 API 为 -1!plt.axes().xaxis.set_major_locator(MaxNLocator(integer=True)) 对我有用。

  • 这对我来说产生了非常奇怪的结果。它将刻度 [0, 2, 4, 8, 10] 变成 [0.0, 1.5, 3.0, 4.5, 7.5, 9.0, 10.5]。根据文档所述,这种情况不应该发生。

  • @Andris 哇,我对此完全不知道。但无论如何,为这个任务调整绘图库似乎很奇怪,你应该修改你的数据。你所指的示例图像似乎已经用绘画或类似的东西编辑过,所以这并不意味着 matplotlib 可以实现这样的输出。

  • 它没有将刻度标签放在给定区域的中间点(如问题的示例图像所示),并且每个第二个(未标记)刻度都缺失。有没有简单的技巧可以实现这些?“2”应该在 2.5 的位置,而不是 2.0。

  • VKP 1月前 0 只看Ta
    引用 15

    这应该更简单:

    (来自 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))
    

    阅读官方文档: https://matplotlib.org/stable/api/ticker_api.html#matplotlib.ticker.MaxNLocator

返回
作者最近主题: