最後,這是我能拿出來與這裏其他的答案的幫助下,最好elsewere是這樣的:
在左邊,x和y僅在一個數量級的一部分上變化,標籤工作得很好。在左邊,x在1和2個數量級之間變化。它工作正常,但方法達到了極限。 y值變化很多數量級,標準標籤會自動使用。
from matplotlib import ticker
from numpy import linspace, logspace, log10, floor
from warnings import warn
def round_to_n(x, n):
''' http://stackoverflow.com/questions/3410976/how-to-round-a-number-to-significant-figures-in-python '''
return round(x, -int(floor(log10(abs(x)))) + (n - 1))
def ticks_log_format(value, index):
''' http://stackoverflow.com/questions/19239297/matplotlib-bad-ticks-labels-for-loglog-twin-axis '''
pwr = floor(log10(value))
base = value/(10 ** pwr)
if pwr == 0 or pwr == 1:
return '${0:d}$'.format(int(value))
if -3 <= pwr < 0:
return '${0:.3g}$'.format(value)
if 0 < pwr <= 3:
return '${0:d}$'.format(int(value))
else:
return '${0:d}\\times10^{{{1:d}}}$'.format(int(base), int(pwr))
def calc_ticks(domain, tick_count, equidistant):
if equidistant:
ticks = logspace(log10(domain[0]), log10(domain[1]), num = tick_count, base = 10)
else:
ticks = linspace(domain[0], domain[1], num = tick_count)
for n in range(1, 6):
if len(set(round_to_n(tick, n) for tick in ticks)) == tick_count:
break
return list(round_to_n(tick, n) for tick in ticks)
''' small domain log ticks '''
def sdlt_x(ax, domain, tick_count = 4, equidistant = True):
''' http://stackoverflow.com/questions/3410976/how-to-round-a-number-to-significant-figures-in-python '''
if min(domain) <= 0:
warn('domain %g-%g contains values lower than 0' % (domain[0], domain[1]))
domain = [max(value, 0.) for value in domain]
ax.set_xscale('log')
ax.set_xlim(domain)
ax.xaxis.set_major_formatter(ticker.FuncFormatter(ticks_log_format))
if log10(max(domain)/min(domain)) > 1.7:
return
ticks = calc_ticks(domain, tick_count = tick_count, equidistant = equidistant)
ax.set_xticks(ticks)
''' any way to prevent this code duplication? '''
def sdlt_y(ax, domain, tick_count = 5, equidistant = True):
''' http://stackoverflow.com/questions/3410976/how-to-round-a-number-to-significant-figures-in-python '''
if min(domain) <= 0:
warn('domain %g-%g contains values lower than 0' % (domain[0], domain[1]))
domain = [max(value, 1e-8) for value in domain]
ax.set_yscale('log')
ax.set_ylim(domain)
ax.yaxis.set_major_formatter(ticker.FuncFormatter(ticks_log_format))
if log10(max(domain)/min(domain)) > 1.7:
return
ticks = calc_ticks(domain, tick_count = tick_count, equidistant = equidistant)
ax.set_yticks(ticks)
''' demo '''
fig, (ax1, ax2,) = plt.subplots(1, 2)
for mi, ma, ax in ((100, 130, ax1,), (10, 400, ax2,),):
x = np.linspace(mi, ma, 50)
y = 1/((x + random(50) * 0.1 * (ma - mi)) ** 4)
ax.scatter(x, y)
sdlt_x(ax, (mi, ma,))
sdlt_y(ax, (min(y), max(y),))
show()
編輯:一個選項更新,以使標籤等距(這樣的值是對數,但可見的位置是等距)。
默認情況下,僅在幾十年內發出滴答聲(而且您還不到十年)您能向我們展示您用來生成此代碼的代碼嗎? – tacaswell
[對數刻度設置刻度]可能的副本(http://stackoverflow.com/questions/14530113/set-ticks-with-logarithmic-scale) – tacaswell
在更多的看,這看起來像你正在做你的所有在hartee/bohr軸上繪圖,使用'twinx'和'twiny'來繪製eV和angstrom軸,但從不繪製任何東西。您需要明確設置其限制以匹配其他軸上的限制(正確轉換)。 – tacaswell