web-dev-qa-db-ja.com

Matplotlib:文字列をカスタムxティックとして追加しますが、既存の(数値)目盛りラベルも保持しますか? matplotlib.pyplot.annotateの代替?

グラフを作成しようとしていますが、注釈を付ける際にいくつか問題があります。

私のグラフのx軸には対数目盛があり、時間を示しています。私ができることは、既存の(ただし予測できない)数値目盛ラベルを100単位、1000単位、10000単位などに維持し、さらにカスタム目盛ラベルをX軸に追加して、より「人間的な」場所を明確にすることです。読み取り可能な」時間間隔が発生します---たとえば、「1週間」、「1か月」、「6か月」などのラベルを付けることができます。

Matplotlib.pyplot.annotate()を使用してポイントにマークを付けることができますが、実際には望みどおりに動作しません。グラフの上にテキストと矢印を本当に必要とせず、カスタムティックマークをいくつか追加したいだけです。何か案は?

18
FakeDIY

ティックを追加したい場合は、axis.xaxis.get_majorticklocs()を使用して既存のティックを取得し、追加するものを追加してから、axis.xaxis.set_ticks(<your updated array>)を使用してティックを設定できます。

別の方法として、縦線を追加することもできます axvline を使用します。利点は、既存の配列にカスタムティックを挿入することを心配する必要がないことですが、手動で行に注釈を付ける必要があります。

さらに別の方法は、カスタムティックを使用してリンクされた軸を追加することです。

16
ev-br

http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.xticks から:

# return locs, labels where locs is an array of tick locations and
# labels is an array of tick labels.
locs, labels = xticks()

したがって、locslabelsを取得し、labelsを好みに合わせて変更するだけです(ダミーの例)。

labels = ['{0} (1 day)','{0} (1 weak)', '{0} (1 year)']
new_labels = [x.format(locs[i]) for i,x  in enumerate(labels)]

次に実行します:

xticks(locs, new_labels)
12
deinonychusaur

これが私の解決策です。主な利点は次のとおりです。

  • 軸を指定できます(ツイン軸の場合、または同時に複数の軸を操作する場合に便利です)。
  • 軸を指定できます(x軸またはy軸に目盛りを付けます)
  • 自動ティックを維持しながら、新しいティックを簡単に追加できます
  • すでに存在するティックを追加すると、自動的に置き換えられます。

コード:

#!/usr/bin/python
from __future__ import division
import matplotlib.pyplot as plt
import numpy as np

#Function to add ticks
def addticks(ax,newLocs,newLabels,pos='x'):
    # Draw to get ticks
    plt.draw()

    # Get existing ticks
    if pos=='x':
        locs = ax.get_xticks().tolist()
        labels=[x.get_text() for x in ax.get_xticklabels()]
    Elif pos =='y':
        locs = ax.get_yticks().tolist()
        labels=[x.get_text() for x in ax.get_yticklabels()]
    else:
        print("WRONG pos. Use 'x' or 'y'")
        return

    # Build dictionary of ticks
    Dticks=dict(Zip(locs,labels))

    # Add/Replace new ticks
    for Loc,Lab in Zip(newLocs,newLabels):
        Dticks[Loc]=Lab

    # Get back tick lists
    locs=list(Dticks.keys())
    labels=list(Dticks.values())

    # Generate new ticks
    if pos=='x':
        ax.set_xticks(locs)
        ax.set_xticklabels(labels)
    Elif pos =='y':
        ax.set_yticks(locs)
        ax.set_yticklabels(labels)


#Get numpy arrays
x=np.linspace(0,2)
y=np.sin(4*x)

#Start figure
fig = plt.figure()
ax=fig.add_subplot(111)

#Plot Arrays
ax.plot(x,y)
#Add a twin axes
axr=ax.twinx()

#Add more ticks
addticks(ax,[1/3,0.75,1.0],['1/3','3/4','Replaced'])
addticks(axr,[0.5],['Miguel'],'y')

#Save figure
plt.savefig('MWE.pdf')  
5
Miguel

上記のミゲルの答えが好きです。かなりうまくいきました。ただし、少し調整する必要があります。以下:

# Get back tick lists
locs=Dticks.keys()
labels=Dticks.values()

に変更する必要があります

# Get back tick lists
locs=list(Dticks.keys())
labels=list(Dticks.values())

Python 2.7 +/3では、Dict.keys()およびDict.values()はdict_keysおよびdict_valuesオブジェクトを返しますが、matplotlibは(明らかに)好きではありません。)これらの2つのオブジェクトの詳細 PEP 3106

1
selimb