2015-09-22 6 views
2

Я пытаюсь создать горизонтальный график, который может динамически меняться с помощью ползунка. Я следил за рецептом на сайте matplotib и хорошо работает для данных line. Код:Интерактивный штриховой график с использованием matplotlib с изменением аннотации

def interactive_pyramid(ages_matrix, year_labels): 
    fig, axs = plt.subplots() 
    plt.subplots_adjust(bottom=0.25) 
    l, = axs.plot(range(len(ages_matrix[0, :])), ages_matrix[0, :]) 
    axs.annotate(year_labels[0], xy=(0.85, 0.85), xycoords="axes fraction") 
    axs.set_ylim([0,800]) 

    pprint (dir(axs)) 
    axcolor = 'lightgoldenrodyellow' 
    axyear = plt.axes([0.25, 0.1, 0.5, 0.1], axisbg=axcolor) 
    syear = Slider(axyear, 'Year', 0, ages_matrix.shape[0] - 1, 0) 

    def update(val): 
     year = syear.val 
     # axs.barh(range(len(ages_matrix[0, :])), ages_matrix[val, :]) 
     l.set_ydata(ages_matrix[val, :]) 
     # axs.annotate(year_labels[year], xy=(0.85, 0.85), xycoords="axes fraction") 
     axs.Annotation.remove() 
     fig.canvas.draw() 
    syear.on_changed(update) 

ages_matrix является 2d ndarray и year_labels является 1d ndarray

два основных вопроса:

  • axs.barh() не возвращает объект с методом set_ydata() сделать не могу измените данные y. если я просто снова рисую данные на объекте axs, он не удаляет предыдущую информацию, что приводит к беспорядку диаграмм.
  • То же самое происходит с аннотациями - это не стирает предыдущий.

Есть ли способ эффективно стереть топор и нарисовать его снова? возможно, каким-то образом обновить холст?

Clutter

+0

Вам необходимо позвонить удалить на экземпляр 'Annotation' объекта. 'barh' возвращает список исправлений, так как теперь вы должны независимо изменять каждую из своих высот. – tacaswell

+0

Спасибо, это помогло. Однако подумал, что это будет более элегантно. – DeanLa

ответ

1

Вот что я придумал:

# Init Chart 
fig, axs = plt.subplots() 
plt.subplots_adjust(bottom=0.25) 
axs.set_xlim([0,ages_matrix.max()*1.05]) 
# Initial Pyramid 
pyramid = axs.barh(np.arange(len(ages_matrix[0, :])) * 5, 
        ages_matrix[0, :], 
        height=4.5) 
# Annotation 
ann = axs.annotate(year_labels[0], xy=(0.85, 0.85), xycoords="axes fraction") 
# Slider 
axcolor = 'lightgoldenrodyellow' 
axyear = plt.axes([0.25, 0.1, 0.5, 0.1], axisbg=axcolor) 
syear = Slider(axyear, 'Year', 0, ages_matrix.shape[0] - 1, 0) 

def update(val): 
    t = syear.val 
    year = np.trunc(year_labels[t]) 
    day = (year_labels[t] - year) * 365 
    ages = ages_matrix[t, :] 
    for i, p in enumerate(pyramid): 
     p.set_width(ages[i]) 
    ann.set_text("Year: {}\nDay: {}".format(int(year), int(day))) 
    fig.canvas.draw() 

enter image description here

Смежные вопросы