Добавление меток к временным рядам, сгруппированным по графику годовой линии по линиям - Matplotlib, Python - PullRequest
1 голос
/ 17 октября 2019

Меня сводит с ума то, что я не могу сделать то, что должно быть достаточно простым. У меня есть временные ряды, которые я сгруппировал по годам, чтобы я мог строить их каждый год и сравнивать их. Когда я строю график, у меня 21 линия, поэтому вместо поля легенды я хотел бы добавить год в конец каждой строки, например, вот этот график (пример): line plot with several lines

Я создал функцию, которая берет любой временной ряд и возвращает этот график, и я изо всех сил пытаюсь добавить эту пользовательскую метку / аннотацию.

Мой код такой:

def plot_by_year(ts):
# first I group the time series (ts) by year:
 year_group = ts.groupby(pd.Grouper(freq ='A'))
 yearly = pd.DataFrame()
 for year, group in year_group:
     yearly[year.year] = group.values.ravel()

# now to plot it, the easy mode is:
 yearly.plot(figsize = (12,14), legend=True)
 plt.gca().legend(loc='center left', bbox_to_anchor=(1, .5));

Тем не менее, это дает мне только поле с легендой за пределами графика (см. График ниже)

line plot

Альтернатива, которую я пробую, следуя эта инструкция такова:

   for rank, column in enumerate(years):
       plt.plot(np.arange(0,13), yearly[column].values, lw=2.5)
       y_pos = yearly[column].values[-1] - 0.5
       plt.text(12, y_pos, rank)

Это дает мне KeyError: 1996, это первый год моих данных. Я пробовал так много вещей, что даже не знаю, что делаю. Помощь!

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Звучит так, будто ваш years отличается от yearly.columns. Может быть, вы просто ошиблись в типах данных (целые или строковые значения?). Попробуйте вместо этого:

fig, ax = plt.subplots()  # probably unnecessary tbh but I prefer working with the ax obj rather than plt
n_points = yearly.shape[0]  # generalize out that 12. This is the number of points in your series. If it's months then I guess it's always 12...
for year in yearly:  # get the column names straight off the dataframe
    ax.plot(np.arange(n_points), yearly[year].values, lw=2.5)
    y_pos = yearly[year].values[-1] - 0.5
    ax.text(n_points, y_pos, year) # You wanted to label it with the column name, not the column index which is what rank would have given you
0 голосов
/ 17 октября 2019

Вы используете Панд для построения графиков. Этот интерфейс немного отличается от того, что я собираюсь описать ниже, но это грубый учебник

 # The following creates a new figure of desired size and 2 subplots
 f, ax = plt.subplots(1,2, figsize=(9,3))

 # the following is a Pandas DataFrame. It doesn't matter how you got it
 df = pd.read_csv('my.csv', sep=r'\s+')

 # here is a plot:
 ax[0].plot(df['x'], np.abs(df['y'])/1000, 
         label="whatever I want")
 ax[1].plot(df['x'], np.abs(df['g'])/1000, 
         label="another  whatever I want")
 # set whatever I want for the labels
 ax[0].set_ylabel("My x-label")
 ax[1].set_ylabel("My Y-label") 

 # the bbox argument controls where the legend is located
 #  bbox_to_anchor=(0.4, .5) for example is inside
 f.legend(loc='center left', bbox_to_anchor=(1, .5))
...