首页 文章

matplotlib:格式化轴偏移值到整数或特定数字

提问于
浏览
88

我有一个matplotlib图,我正在绘制数据,总是被称为纳秒(1e-9) . 在y轴上,如果我有数十纳秒的数据,即 . 在图44e-9中,轴上的值显示为4.4,其中1e-8作为偏移 . 反正是否强制轴显示44与1e-9偏移?

我的x轴也是如此,其中轴显示为5.54478e4,我宁愿它显示55447的偏移(整数,没有小数 - 这里的值是以天为单位) .

我尝试过这样的事情:

p = axes.plot(x,y)
p.ticklabel_format(style='plain')

对于x轴,但这不起作用,虽然我可能错误地使用它或误解了文档中的某些东西,有人能指出我正确的方向吗?

谢谢,乔纳森

Problem illustration


我尝试用格式化程序做一些事情,但还没找到任何解决方案......:

myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)

myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)

在旁注中,我实际上对“偏移数”对象实际存在的位置感到困惑...它是主要/次要刻度的一部分吗?

8 回答

  • 4

    我有完全相同的问题,这两行修复了问题:

    y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
    ax.yaxis.set_major_formatter(y_formatter)
    
  • 5

    更简单的解决方案是简单地自定义刻度标签 . 举个例子:

    from pylab import *
    
    # Generate some random data...
    x = linspace(55478, 55486, 100)
    y = random(100) - 0.5
    y = cumsum(y)
    y -= y.min()
    y *= 1e-8
    
    # plot
    plot(x,y)
    
    # xticks
    locs,labels = xticks()
    xticks(locs, map(lambda x: "%g" % x, locs))
    
    # ytikcs
    locs,labels = yticks()
    yticks(locs, map(lambda x: "%.1f" % x, locs*1e9))
    ylabel('microseconds (1E-9)')
    
    show()
    

    alt text

    请注意在y轴情况下,我将值乘以 1e9 ,然后在y标签中提到该常量


    EDIT

    另一种选择是通过手动将其文本添加到图的顶部来伪造指数乘数:

    locs,labels = yticks()
    yticks(locs, map(lambda x: "%.1f" % x, locs*1e9))
    text(0.0, 1.01, '1e-9', fontsize=10, transform = gca().transAxes)
    

    EDIT2

    您也可以以相同的方式格式化x轴偏移值:

    locs,labels = xticks()
    xticks(locs, map(lambda x: "%g" % x, locs-min(locs)))
    text(0.92, -0.07, "+%g" % min(locs), fontsize=10, transform = gca().transAxes)
    

    alt text

  • 11

    你必须子类 ScalarFormatter 做你需要的... _set_offset 只需添加一个常量,你想设置 ScalarFormatter.orderOfMagnitude . 不幸的是,当调用 ScalarFormatter 实例来格式化轴刻度标签时,手动设置 orderOfMagnitude 赢了't do anything, as it' s重置 . 它不应该找到一种更简单的方法来完成你想要的......这是一个例子:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.ticker import ScalarFormatter, FormatStrFormatter
    
    class FixedOrderFormatter(ScalarFormatter):
        """Formats axis ticks using scientific notation with a constant order of 
        magnitude"""
        def __init__(self, order_of_mag=0, useOffset=True, useMathText=False):
            self._order_of_mag = order_of_mag
            ScalarFormatter.__init__(self, useOffset=useOffset, 
                                     useMathText=useMathText)
        def _set_orderOfMagnitude(self, range):
            """Over-riding this to avoid having orderOfMagnitude reset elsewhere"""
            self.orderOfMagnitude = self._order_of_mag
    
    # Generate some random data...
    x = np.linspace(55478, 55486, 100) 
    y = np.random.random(100) - 0.5
    y = np.cumsum(y)
    y -= y.min()
    y *= 1e-8
    
    # Plot the data...
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(x, y, 'b-')
    
    # Force the y-axis ticks to use 1e-9 as a base exponent 
    ax.yaxis.set_major_formatter(FixedOrderFormatter(-9))
    
    # Make the x-axis ticks formatted to 0 decimal places
    ax.xaxis.set_major_formatter(FormatStrFormatter('%0.0f'))
    plt.show()
    

    产生的结果如下:
    alt text

    而默认格式如下:
    alt text

    希望那有所帮助!

    编辑:对于它的 Value ,我不知道偏移标签所在的位置......手动设置它会稍微容易些,但我无法弄清楚如何这样做......我感觉到了必须有一个比这一切更简单的方法 . 但是它有效!

  • 5

    与Amro的答案类似,您可以使用FuncFormatter

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.ticker import FuncFormatter
    
    # Generate some random data...
    x = np.linspace(55478, 55486, 100) 
    y = np.random.random(100) - 0.5
    y = np.cumsum(y)
    y -= y.min()
    y *= 1e-8
    
    # Plot the data...
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(x, y, 'b-')
    
    # Force the y-axis ticks to use 1e-9 as a base exponent 
    ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: ('%.1f')%(x*1e9)))
    ax.set_ylabel('microseconds (1E-9)')
    
    # Make the x-axis ticks formatted to 0 decimal places
    ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '%.0f'%x))
    plt.show()
    
  • 28

    我认为更优雅的方法是使用自动收报机格式化程序 . 以下是xaxis和yaxis的示例:

    from pylab import *
    from matplotlib.ticker import MultipleLocator, FormatStrFormatter
    
    majorLocator   = MultipleLocator(20)
    xFormatter = FormatStrFormatter('%d')
    yFormatter = FormatStrFormatter('%.2f')
    minorLocator   = MultipleLocator(5)
    
    
    t = arange(0.0, 100.0, 0.1)
    s = sin(0.1*pi*t)*exp(-t*0.01)
    
    ax = subplot(111)
    plot(t,s)
    
    ax.xaxis.set_major_locator(majorLocator)
    ax.xaxis.set_major_formatter(xFormatter)
    ax.yaxis.set_major_formatter(yFormatter)
    
    #for the minor ticks, use no labels; default NullFormatter
    ax.xaxis.set_minor_locator(minorLocator)
    
  • 1

    添加 set_scientific(False) 后,Gonzalo的解决方案开始为我工作:

    ax=gca()
    fmt=matplotlib.ticker.ScalarFormatter(useOffset=False)
    fmt.set_scientific(False)
    ax.xaxis.set_major_formatter(fmt)
    
  • 96

    正如评论和in this answer中所指出的那样,通过执行以下操作,可以全局关闭偏移量:

    matplotlib.rcParams['axes.formatter.useoffset'] = False
    
  • 34

    对于第二部分,没有再次手动重置所有刻度,这是我的解决方案:

    class CustomScalarFormatter(ScalarFormatter):
        def format_data(self, value):
            if self._useLocale:
                s = locale.format_string('%1.2g', (value,))
            else:
                s = '%1.2g' % value
            s = self._formatSciNotation(s)
            return self.fix_minus(s)
    xmajorformatter = CustomScalarFormatter()  # default useOffset=True
    axes.get_xaxis().set_major_formatter(xmajorformatter)
    

    显然你可以将格式字符串设置为你想要的任何东西 .

相关问题