简体   繁体   English

使用带有注释更改的 matplotlib 的交互式条形图

[英]Interactive bar plot using matplotlib with annotation change

I'm trying to create a horizontal bar plot that can dynamically change with a slider.我正在尝试创建一个可以随滑块动态更改的水平条形图。 I've followed the recipe on the matplotib website and it works well for line data.我遵循了 matplotib 网站上的配方,它适用于line数据。 The code:编码:

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 is a 2d ndarray and year_labels is a 1d ndarray Ages_matrix 是一个2d ndarray而 year_labels 是一个一1d ndarray

two main questions:两个主要问题:

  • the axs.barh() does not return an object with a set_ydata() method do I can't change the y data. axs.barh()不返回带有set_ydata()方法的对象,我无法更改 y 数据。 if I just draw the data again on the axs object it doesn't erase the previous information, resulting in a clutter of charts.如果我只是在 axs 对象上再次绘制数据,它不会删除以前的信息,从而导致图表混乱。
  • the same happens with annotations - it does not erase the previous one.注释也会发生同样的情况 - 它不会删除前一个。

Is there any way to efficiently erase the ax and draw it again?有什么方法可以有效地擦除斧头并再次绘制它? maybe some way to refresh the canvas?也许某种方式来刷新画布?

杂乱

That's what I came up with:这就是我想出的:

# 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()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM