【问题标题】:matplotlib: format axis offset-values to whole numbers or specific numbermatplotlib:将轴偏移值格式化为整数或特定数字
【发布时间】:2011-04-10 07:03:05
【问题描述】:

我有一个 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 轴,但这不起作用,尽管我可能使用不正确或误解了文档中的某些内容,有人能指出我正确的方向吗?

谢谢, 乔纳森


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

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)

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

【问题讨论】:

  • 你试过set_units吗? matplotlib.sourceforge.net/api/…(我无法尝试,因为我这里没有matplotlib。)
  • 我检查了 set_units 函数,它似乎比必要的复杂得多(必须编写/添加一个额外的模块??-basic_units?)。必须有一种方法来编辑刻度的格式。 units / set_unit 函数似乎更像是单位转换。不过感谢您的提示,它使我找到了我正在寻找的其他一些解决方案!
  • 如果默认关闭,请考虑 rcParams 关闭:rcParams["axes.formatter.useoffset"] = False 在这里:stackoverflow.com/questions/24171064/…

标签: python matplotlib


【解决方案1】:

我遇到了完全相同的问题,这些行解决了问题:

from matplotlib.ticker import ScalarFormatter

y_formatter = ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)

【讨论】:

  • 这是一个快速简单的答案。谢谢。
  • 单行是:ax.get_yaxis().get_major_formatter().set_useOffset(False)
  • 对于像我这样的菜鸟,不要忘记 from matplotlib.ticker import ScalarFormatter 让 @Gonzalo 的代码工作或简单地使用上面的 @Dataman 的解决方案
【解决方案2】:

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

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

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


编辑

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

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)

【讨论】:

  • 一开始我就是这么做的。不幸的是,我找不到一种简单的方法来设置/显示轴乘数(除了像你所做的那样明确地将它放在 y 轴标签中。)。如果您不介意没有轴乘数标签,这是更简单的方法。无论哪种方式,请向我 +1。
  • @Joe Kington:您可以手动将其添加为文本...参见上面的编辑:)
  • 太棒了!我将尝试使用 x 轴标签的方法。我将取第一个 x 值的地板,然后从每个 x 值中删除它并添加一个“+minxval”作为标签。我不知道如何格式化 x-tick 偏移量。我对偏移量的大小很好,我只需要它显示为非指数值。
  • 哇。很好地展示了您如何真正控制 matplotlib 并根据您的需要进行调整,并真正为您的情节增添一些活力。
  • 图中1e-9的fontsize怎么改?
【解决方案3】:

你必须继承ScalarFormatter 来做你需要的事情..._set_offset 只是添加一个常量,你想设置ScalarFormatter.orderOfMagnitude。不幸的是,手动设置orderOfMagnitude 不会做任何事情,因为当调用ScalarFormatter 实例来格式化轴刻度标签时它会被重置。它不应该这么复杂,但我找不到更简单的方法来做你想做的事......这是一个例子:

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

这会产生如下内容:

然而,默认格式如下所示:

希望能有所帮助!

编辑:对于它的价值,我也不知道偏移标签所在的位置......手动设置它会稍微容易一些,但我不知道该怎么做......我感觉必须有比这一切更简单的方法。但它确实有效!

【讨论】:

  • 谢谢!子类化 ScalarFormatter 效果很好!但我想我没有明确说明我想要的 x 轴是什么。我想保留 x 轴的偏移量,但要格式化偏移量的值,使其不显示为指数。
  • 这是唯一对我有用的方法!谢谢:)
【解决方案4】:

与 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()

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        我认为更优雅的方法是使用股票代码格式化程序。以下是 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)
        

        【讨论】:

        • 这没有回答问题,即如何指定偏移量和/或科学记数法中使用的因子
        • @nordev 即使我的回答没有具体回答问题,它仍然给出了提示。消息是您可以选择另一个格式化程序并从我的示例中获取您想要的而不是日期。在科学界,儒略日是常态,或者你可以像我的例子一样使用日期。我试图建议的是可以采取不同的方法。有时可能会问一个问题,因为这个人目前没有更好的主意。不应放弃或不尊重替代解决方案。总而言之,我不配获得 -1 票。
        【解决方案8】:

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

        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)
        

        显然您可以将格式字符串设置为您想要的任何内容。

        【讨论】:

        • 不幸的是,我还没有调查如何将乘数设置为问题的第一部分。
        猜你喜欢
        • 1970-01-01
        • 2011-09-27
        • 1970-01-01
        • 1970-01-01
        • 2011-11-06
        • 2019-10-02
        • 2011-01-10
        • 2014-11-16
        相关资源
        最近更新 更多