48

y 軸の単位が異なる 2 つのデータセットをプロットしています。目盛りとグリッド線を両方の y 軸に揃える方法はありますか?

最初の画像は私が取得したものを示し、2 番目の画像は取得したいものを示しています。

これは私がプロットするために使用しているコードです:

import seaborn as sns
import numpy as np
import pandas as pd

np.random.seed(0)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0, 1, size=10)))
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(10, 20, size=10)), color='r')

望ましくない動作の例

望まれる行動の例

4

7 に答える 7

32

これが最もきれいな方法かどうかはわかりませんが、1行で修正できます。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd

np.random.seed(0)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0, 1, size=10)))
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(10, 20, size=10)), color='r')

# ADD THIS LINE
ax2.set_yticks(np.linspace(ax2.get_yticks()[0], ax2.get_yticks()[-1], len(ax1.get_yticks())))

plt.show()
于 2015-04-09T15:39:07.997 に答える
16

ax.grid(None)グリッドの軸の 1 つを無効にすることで解決できます。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.plot(pd.Series(np.random.uniform(0, 1, size=10)))
ax2 = ax1.twinx()
ax2.plot(pd.Series(np.random.uniform(10, 20, size=10)), color='r')
ax2.grid(None)

plt.show()

図 結果

于 2015-03-17T12:49:17.950 に答える
13

私は、Matplotlib 軸オブジェクト ax1、ax2、および floats minresax1 minresax2 を取るこの関数を作成しました。

def align_y_axis(ax1, ax2, minresax1, minresax2):
    """ Sets tick marks of twinx axes to line up with 7 total tick marks

    ax1 and ax2 are matplotlib axes
    Spacing between tick marks will be a factor of minresax1 and minresax2"""

    ax1ylims = ax1.get_ybound()
    ax2ylims = ax2.get_ybound()
    ax1factor = minresax1 * 6
    ax2factor = minresax2 * 6
    ax1.set_yticks(np.linspace(ax1ylims[0],
                               ax1ylims[1]+(ax1factor -
                               (ax1ylims[1]-ax1ylims[0]) % ax1factor) %
                               ax1factor,
                               7))
    ax2.set_yticks(np.linspace(ax2ylims[0],
                               ax2ylims[1]+(ax2factor -
                               (ax2ylims[1]-ax2ylims[0]) % ax2factor) %
                               ax2factor,
                               7))

ティックが 7 つになるようにティックを計算して設定します。最低の目盛りは現在の最低の目盛りに対応し、各目盛り間の間隔が minrexax1 または minrexax2 の整数倍になるように最高の目盛りを増やします。

一般的にするために、7表示されるティックの総数を変更6して、必要なティックの総数を設定し、ティックの総数から 1 を引いた値に変更することができます。

これをmatplotlib.ticker.LinearLocatorに組み込むためにプルリクエストを入れました:

https://github.com/matplotlib/matplotlib/issues/6142

将来的には (おそらく Matplotlib 2.0?)、試してください:

import matplotlib.ticker
nticks = 11
ax1.yaxis.set_major_locator(matplotlib.ticker.LinearLocator(nticks))
ax2.yaxis.set_major_locator(matplotlib.ticker.LinearLocator(nticks))

それはうまく機能し、両方の y 軸に便利な目盛りを選択する必要があります。

于 2016-03-09T23:31:09.793 に答える
0

軸ラベルを使用している場合、目盛りの数値の精度により、Leo のソリューションによって軸ラベルが押し出される可能性があります。

したがって、レオのソリューションのようなものに加えて (ここで繰り返します)、

ax2.set_yticks(np.linspace(ax2.get_yticks()[0],ax2.get_yticks()[-1],len(ax1.get_yticks())))

この回答autolayoutに記載されているように、設定を使用できます。たとえば、スクリプトの早い段階で次のように更新できます。rcParams

from matplotlib import rcParams
rcParams.update({'figure.autolayout': True})

いくつかのテスト ケースでは、これにより期待される結果が生成され、整列した目盛りとラベルの両方が出力に完全に含まれているように見えます。

于 2016-03-14T18:04:57.870 に答える