Matplotlib日志刻度刻度标签号格式

2024-09-25 10:25:26 发布

您现在位置:Python中文网/ 问答频道 /正文

使用matplotlib当为轴指定日志刻度时,标记该轴的默认方法是使用幂为10的数字,例如10^6。是否有一种简单的方法可以将所有这些标签更改为它们的完整数字表示?例1、10、100等

请注意,我不知道什么范围的权力将是,并希望支持一个任意的范围(包括否定)。


Tags: 方法标记matplotlib数字标签权力刻度
3条回答

我发现Joe'sTom's答案非常有用,但是在对这些答案的评论中有很多有用的细节。以下是两种情况的摘要:

范围大于1

下面是类似于Joe的示例代码,但范围更大:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.axis([1, 10000, 1, 1000000])
ax.loglog()

plt.show()

用科学符号表示这样的情节: Default plot with scientific notation

在乔的回答中,我使用ScalarFormatter,但我也调用set_scientific(False)。当规模达到或超过1000000时,这是必要的。

import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter

fig, ax = plt.subplots()
ax.axis([1, 10000, 1, 1000000])
ax.loglog()
for axis in [ax.xaxis, ax.yaxis]:
    formatter = ScalarFormatter()
    formatter.set_scientific(False)
    axis.set_major_formatter(formatter)

plt.show()

Plot with integer ticks

低于1的范围

在汤姆的回答中,当范围小于1时,会发生以下情况:

import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter

fig, ax = plt.subplots()
ax.axis([0.01, 10000, 1, 1000000])
ax.loglog()
for axis in [ax.xaxis, ax.yaxis]:
    formatter = ScalarFormatter()
    formatter.set_scientific(False)
    axis.set_major_formatter(formatter)

plt.show()

它将x轴上的前两个刻度显示为零。

Plot with ticks labelled as zero

切换到FuncFormatter可以处理这个问题。同样,我对1000000或更高的数字也有问题,但是给格式字符串添加一个精度就解决了这个问题。

import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

fig, ax = plt.subplots()
ax.axis([0.01, 10000, 1, 1000000])
ax.loglog()
for axis in [ax.xaxis, ax.yaxis]:
    formatter = FuncFormatter(lambda y, _: '{:.16g}'.format(y))
    axis.set_major_formatter(formatter)

plt.show()

enter image description here

我发现,如果所有的tick值都大于或等于1,那么使用ScalarFormatter非常好。但是,如果您在数字<1处有一个勾号,ScalarFormatter会将勾号标签打印为0

enter image description here

我们可以使用matplotlib^{}模块中的^{}来解决此问题。最简单的方法是使用lambda函数和g格式说明符(感谢注释中的@lenz)。

import matplotlib.ticker as ticker

ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda y, _: '{:g}'.format(y)))

注意在我最初的回答中,我没有使用g格式,而是使用了这个lambda函数和FuncFormatter来将数字>= 1设置为其整数值,将数字<1设置为其十进制值,并要求最小的小数位数(即0.1, 0.01, 0.001,等等)。它假设您只是在base10值上设置勾号。

import matplotlib.ticker as ticker
import numpy as np

ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda y,pos: ('{{:.{:1d}f}}'.format(int(np.maximum(-np.log10(y),0)))).format(y)))

enter image description here

为了清楚起见,这里的lambda函数以更详细但也更容易理解的方式写出:

def myLogFormat(y,pos):
    # Find the number of decimal places required
    decimalplaces = int(np.maximum(-np.log10(y),0))     # =0 for numbers >=1
    # Insert that number into a format string
    formatstring = '{{:.{:1d}f}}'.format(decimalplaces)
    # Return the formatted tick label
    return formatstring.format(y)

ax.yaxis.set_major_formatter(ticker.FuncFormatter(myLogFormat))

当然,只要改变格式化程序。

例如,如果我们有这个情节:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.axis([1, 10000, 1, 100000])
ax.loglog()

plt.show()

enter image description here

您可以手动设置刻度标签,但当您缩放/平移/等时,刻度位置和标签将被固定。因此,最好更改格式化程序。默认情况下,对数刻度使用LogFormatter,这将以科学记数法格式化值。要将格式化程序更改为线性轴(ScalarFormatter)的默认值,请使用例如

from matplotlib.ticker import ScalarFormatter
for axis in [ax.xaxis, ax.yaxis]:
    axis.set_major_formatter(ScalarFormatter())

enter image description here

相关问题 更多 >