3

matplotlib で loglog プロットを作成しています。下の図に見られるように、デフォルトの目盛りは不適切に (せいぜい) 選択されています。右の y 軸にはまったくありません (線形に相当します)。両方の x 軸には 1 つしかありません。

デフォルトの目盛りが悪い loglog プロット

プロットごとに手動で指定せに、適切な数の目盛りをラベルで取得する方法はありますか?


編集: 正確なコードは長すぎますが、問題の短い例を次に示します。

x = linspace(4, 18, 20)
y = 1 / (x ** 4)
fig = figure()
ax = fig.add_axes([.1, .1, .8, .8])
ax.loglog(x, y)
ax.set_xlim([4, 18])
ax2 = ax.twiny()
ax2.set_xlim([4 / 3., 18 / 3.])
ax2.set_xscale('log')
show()
4

2 に答える 2

1

私はあなたが示すようなものと戦ってきました(軸範囲の主要な目盛りは1つだけです)。matplotlibの目盛りフォーマッタはどれも私を満足させなかったので、私はmatplotlib.ticker.FuncFormatter自分が望むものを達成するために使用しています。2 軸でテストしたことはありませんが、とにかく動作するはずだと感じています。

import matplotlib.pyplot as plt
from matplotlib import ticker
import numpy as np

#@Mark: thanks for the suggestion :D
mi, ma, conv = 4, 8, 1./3.
x = np.linspace(mi, ma, 20)
y = 1 / (x ** 4)

fig, ax = plt.subplots()

ax.plot(x, y)  # plot the lines
ax.set_xscale('log') #convert to log
ax.set_yscale('log')

ax.set_xlim([0.2, 1.8])  #large enough, but should show only 1 tick

def ticks_format(value, index):
    """
    This function decompose value in base*10^{exp} and return a latex string.
    If 0<=value<99: return the value as it is.
    if 0.1<value<0: returns as it is rounded to the first decimal
    otherwise returns $base*10^{exp}$
    I've designed the function to be use with values for which the decomposition
    returns integers
    """
    exp = np.floor(np.log10(value))
    base = value/10**exp
    if exp == 0 or exp == 1:
        return '${0:d}$'.format(int(value))
    if exp == -1:
        return '${0:.1f}$'.format(value)
    else:
        return '${0:d}\\times10^{{{1:d}}}$'.format(int(base), int(exp))

# here specify which minor ticks per decate you want
# likely all of them give you a too crowed axis
subs = [1., 3., 6.]
# set the minor locators
ax.xaxis.set_minor_locator(ticker.LogLocator(subs=subs))
ax.yaxis.set_minor_locator(ticker.LogLocator(subs=subs))
# remove the tick labels for the major ticks: 
# if not done they will be printed with the custom ones (you don't want it)
# plus you want to remove them to avoid font missmatch: the above function 
# returns latex string, and I don't know how matplotlib does exponents in labels
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.yaxis.set_major_formatter(ticker.NullFormatter())
# set the desired minor tick labels using the above function
ax.xaxis.set_minor_formatter(ticker.FuncFormatter(ticks_format))
ax.yaxis.set_minor_formatter(ticker.FuncFormatter(ticks_format))

私が得る図は次のとおりここに画像の説明を入力です。

もちろん、x 軸と y 軸に異なるマイナー ロケータを設定できます。また、入力パラメータとして軸インスタンスandまたはandticks_formatを受け入れる関数に、 から最後まですべてをラップできます。axsubssubsxsubsy

これがお役に立てば幸いです

于 2013-10-08T09:08:41.220 に答える