2017-04-12 11 views
2

私は図形ウィンドウで最大値に自動的に注釈を付ける方法を理解しようとしています。 .annotate()メソッドを使用して任意の点に注釈を付けるためにx、y座標を手動で入力することでこれを行うことができますが、注釈を自動的に、または最大点を単独で探したいと思います。このようなpyplotの最大値に自動的に注釈を付ける方法は?

import matplotlib.pyplot as plt 
import numpy as np 
import pandas as pd 
from pandas import Series, DataFrame 

df = pd.read_csv('macrodata.csv') #Read csv file into dataframe 
years = df['year'] #Get years column 
infl = df['infl'] #Get inflation rate column 

fig10 = plt.figure() 
win = fig10.add_subplot(1,1,1) 
fig10 = plt.plot(years, infl, lw = 2) 

fig10 = plt.xlabel("Years") 
fig10 = plt.ylabel("Inflation") 
fig10 = plt.title("Inflation with Annotations") 

Here's the figure that it generates

答えて

5

私は一緒に行くためにmacrodata.csvのデータを持っていません。しかし、一般的に、軸データをリストとしてxyとした場合、次の方法を使用して、自動配置をmaxにすることができます。

ワーキングコード:

import numpy as np 
import matplotlib.pyplot as plt 

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

x=[1,2,3,4,5,6,7,8,9,10] 
y=[1,1,1,2,10,2,1,1,1,1] 
line, = ax.plot(x, y) 

ymax = max(y) 
xpos = y.index(ymax) 
xmax = x[xpos] 

ax.annotate('local max', xy=(xmax, ymax), xytext=(xmax, ymax+5), 
      arrowprops=dict(facecolor='black', shrink=0.05), 
      ) 

ax.set_ylim(0,20) 
plt.show() 

プロット:
enter image description here

+0

TypeError: 'RangeIndex'オブジェクトが呼び出し可能ではありません - 配列ではなくDataFrame内に軸データがあります。これがエラーメッセージを受け取るのはなぜですか?コードを見るだけで、うまくいくはずです。 – shadewolf

+0

私のコードのどの行にエラーがありますか? –

+0

12行目:(xpos = y.index(ymax)) – shadewolf

0

何かが動作します:ここで

は私のコードは、これまでのところだ

infl_max_index = np.where(infl == max(infl)) #get the index of the maximum inflation 
infl_max = infl[infl_max_index] # get the inflation corresponding to this index 
year_max = year[infl_max_index] # get the year corresponding to this index 

plt.annotate('max inflation', xy=(year_max, infl_max)) 
+0

FYI、['argmax'](https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html)は、最大のインデックスを取得するための組み込みメソッドです。 – zephyr

+0

@Alex私はこれを知っています:ValueError:MultiIndexでタプルすることはできますか – shadewolf

7

xyをプロットする配列の場合、あなたはの座標を取得します最大ビア:

xmax = x[numpy.argmax(y)] 
ymax = y.max() 

これは、単にデータで呼び出すことのできる機能に組み込むことができます。

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(-2,8, num=301) 
y = np.sinc((x-2.21)*3) 


fig, ax = plt.subplots() 
ax.plot(x,y) 

def annot_max(x,y, ax=None): 
    xmax = x[np.argmax(y)] 
    ymax = y.max() 
    text= "x={:.3f}, y={:.3f}".format(xmax, ymax) 
    if not ax: 
     ax=plt.gca() 
    bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72) 
    arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=60") 
    kw = dict(xycoords='data',textcoords="axes fraction", 
       arrowprops=arrowprops, bbox=bbox_props, ha="right", va="top") 
    ax.annotate(text, xy=(xmax, ymax), xytext=(0.94,0.96), **kw) 

annot_max(x,y) 


ax.set_ylim(-0.3,1.5) 
plt.show() 

enter image description here

+0

ちょうど綺麗です:) –

+0

どのメソッドがどの種類の入力で動作するのか混乱していたので、この答えに示されたメソッドは入力データ** numpy配列**、** pandasシリーズ**です。純粋なpythonリストは機能しません。この場合は、[@ Anil_Mの答え](http://stackoverflow.com/a/43375405/4124317)を参照してください。 – ImportanceOfBeingErnest

0

responseに@ImportanceOfBeingErnestによって提案された方法は本当にきちんとしているが、データはパンダのデータ内にある場合、それは動作しません。 ([0,1,2、..、N])ではな​​く、インデックスにプロットすることが望ましく、その値はx's-である。

私は前述の解決策を適応させて、パンダplotの機能で使用しました。私はまた対称のmin関数を書いた。

def annot_max(x,y, ax=None): 
    maxIxVal = np.argmax(y); 
    zeroBasedIx = np.argwhere(y.index==maxIxVal).flatten()[0]; 
    xmax = x[zeroBasedIx]; 
    ymax = y.max() 
    text= "k={:d}, measure={:.3f}".format(xmax, ymax) 
    if not ax: 
     ax=plt.gca() 
    bbox_props = dict(boxstyle="round,pad=0.3", fc="w", ec="k", lw=0.72) 
    arrowprops=dict(arrowstyle="-",connectionstyle="arc3,rad=0.1") 
    kw = dict(xycoords='data',textcoords="axes fraction", 
       arrowprops=arrowprops, bbox=bbox_props, ha="right", va="top") 
    ax.annotate(text, xy=(xmax, ymax), xytext=(0.94,0.90), **kw) 

def annot_min(x,y, ax=None): 
    minIxVal = np.argmin(y); 
    zeroBasedIx = np.argwhere(y.index==minIxVal).flatten()[0]; 
    xmin = x[zeroBasedIx]; 
    ymin = y.min() 
    text= "k={:d}, measure={:.3f}".format(xmin, ymin) 
    if not ax: 
     ax=plt.gca() 
    bbox_props = dict(boxstyle="round,pad=0.3", fc="w", ec="k", lw=0.72) 
    arrowprops=dict(arrowstyle="-",connectionstyle="arc3,rad=0.1") 
    kw = dict(xycoords='data',textcoords="axes fraction", 
       arrowprops=arrowprops, bbox=bbox_props, ha="right", va="top") 
    ax.annotate(text, xy=(xmin, ymin), xytext=(0.94,0.90), **kw) 

使用は、たとえば、単純です:

ax = df[Series[0]].plot(grid=True, use_index=True, \ 
        title=None); 
annot_max(df[Series[0]].index,df[Series[0]],ax); 
plt.show(); 

私は、これは誰にどんな助けになるでしょう願っています。

関連する問題