Nat*_*ski 40 python graphing numpy matplotlib
在matplotlib为轴指定对数刻度时,标记该轴的默认方法是使用10到一个幂的数字,例如.10 ^ 6.是否有一种简单的方法可以将所有这些标签更改为完整的数字表示?例如.1,10,100等
请注意,我不知道功率范围是什么,并且想要支持任意范围(包括负数).
Joe*_*ton 52
当然,只需更改格式化程序即可.
例如,如果我们有这个情节:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.axis([1, 10000, 1, 100000])
ax.loglog()
plt.show()
Run Code Online (Sandbox Code Playgroud)

您可以手动设置刻度标签,但在缩放/平移/等时,刻度位置和标签将被修复.因此,最好更改格式化程序:
from matplotlib.ticker import ScalarFormatter
for axis in [ax.xaxis, ax.yaxis]:
axis.set_major_formatter(ScalarFormatter())
Run Code Online (Sandbox Code Playgroud)

tmd*_*son 34
我发现,使用ScalarFormatter是伟大的,如果你所有的刻度值大于或等于1.但是,如果你在一些有蜱<1,在ScalarFormatter打印刻度标记为0.
我们可以使用FuncFormattermatplotlib ticker模块来解决这个问题.最简单的方法是使用lambda函数和g格式说明符(感谢评论中的@lenz).
import matplotlib.ticker as ticker
ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda y, _: '{:g}'.format(y)))
Run Code Online (Sandbox Code Playgroud)
请注意我的原始答案我没有使用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)))
Run Code Online (Sandbox Code Playgroud)
为清楚起见,这里的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))
Run Code Online (Sandbox Code Playgroud)
我发现Joe和Tom的答案非常有帮助,但在这些答案的评论中有很多有用的细节.以下是两种方案的摘要:
这是像Joe的示例代码,但具有更高的范围:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.axis([1, 10000, 1, 1000000])
ax.loglog()
plt.show()
Run Code Online (Sandbox Code Playgroud)
在Joe的回答中,我使用了一个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()
Run Code Online (Sandbox Code Playgroud)
正如在汤姆的回答中,这是当范围低于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()
Run Code Online (Sandbox Code Playgroud)
这会将x轴上的前两个刻度显示为零.
切换到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()
Run Code Online (Sandbox Code Playgroud)
关于这些问题
如果我想将数字更改为1、5、10、20怎么办?
– 2015年7月10日在13:26阿罗哈我想在两者之间添加刻度线,例如50,200等。我该怎么做?我尝试了set_xticks [50.0,200.0],但这似乎不起作用!– ThePredator 2015年8月3日,12:54
但是使用ax.axis([1,100,1,100]),ScalarFormatter给出了1.0、10.0,...,这不是我想要的。我希望它给出整数... – CPBL 2015年12月7日在20:22
您可以使用MINOR格式化程序解决此类问题:
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter("%.8f"))
ax.set_yticks([0.00000025, 0.00000015, 0.00000035])
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我正在使用这种格式方案,我认为它可以解决与日志标量格式有关的大多数问题;对于数据> 1.0或x轴格式,可以执行相同的操作:
plt.ylabel('LOGARITHMIC PRICE SCALE')
plt.yscale('log')
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter("%.8f"))
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter("%.8f"))
#####################################################
#force 'autoscale'
#####################################################
yd = [] #matrix of y values from all lines on plot
for n in range(len(plt.gca().get_lines())):
line = plt.gca().get_lines()[n]
yd.append((line.get_ydata()).tolist())
yd = [item for sublist in yd for item in sublist]
ymin, ymax = np.min(yd), np.max(yd)
ax.set_ylim([0.9*ymin, 1.1*ymax])
#####################################################
z = []
for i in [0.0000001, 0.00000015, 0.00000025, 0.00000035,
0.000001, 0.0000015, 0.0000025, 0.0000035,
0.00001, 0.000015, 0.000025, 0.000035,
0.0001, 0.00015, 0.00025, 0.00035,
0.001, 0.0015, 0.0025, 0.0035,
0.01, 0.015, 0.025, 0.035,
0.1, 0.15, 0.25, 0.35]:
if ymin<i<ymax:
z.append(i)
ax.set_yticks(z)
Run Code Online (Sandbox Code Playgroud)
有关“强制自动缩放”的评论,请参见: Python matplotlib对数自动缩放
产生:
然后创建一个通用机器:
# user controls
#####################################################
sub_ticks = [10,11,12,14,16,18,22,25,35,45] # fill these midpoints
sub_range = [-8,8] # from 100000000 to 0.000000001
format = "%.8f" # standard float string formatting
# set scalar and string format floats
#####################################################
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter(format))
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())
ax.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter(format))
#force 'autoscale'
#####################################################
yd = [] #matrix of y values from all lines on plot
for n in range(len(plt.gca().get_lines())):
line = plt.gca().get_lines()[n]
yd.append((line.get_ydata()).tolist())
yd = [item for sublist in yd for item in sublist]
ymin, ymax = np.min(yd), np.max(yd)
ax.set_ylim([0.9*ymin, 1.1*ymax])
# add sub minor ticks
#####################################################
set_sub_formatter=[]
for i in sub_ticks:
for j in range(sub_range[0],sub_range[1]):
set_sub_formatter.append(i*10**j)
k = []
for l in set_sub_formatter:
if ymin<l<ymax:
k.append(l)
ax.set_yticks(k)
#####################################################
Run Code Online (Sandbox Code Playgroud)
产量: