使用 matplotlib 对簇柱形图和折线图进行动画处理

问题描述 投票:0回答:1

我正在尝试制作一个逐帧更新的动画图表,以使最终结果对于每个 x 轴条目都有两列(在年份或年份和 Q 之间确实有所不同,但无论哪种方式都是字符串)和一条线。

我有两个数据框,我读到的数据框在这种情况下很有帮助。

df


{'GDP': {'2013Q1': 6.2, '2013Q2': 6.1, '2013Q3': 6.63, '2013Q4': 6.63, '2014Q1': 5.29, '2014Q2': 5.29, '2014Q3': 5.29, '2014Q4': 5.29, '2015Q1': 3.88, '2015Q2': 3.88, '2015Q3': 3.88, '2015Q4': 3.88, '2016Q1': 1.01, '2016Q2': 1.01, '2016Q3': 1.01, '2016Q4': 1.01}, 'GDP, nominal’: {'2013Q1': -1.78, '2013Q2': -1.72, '2013Q3': -1.72, '2013Q4': -1.72, '2014Q1': 2.9, '2014Q2': 2.46, '2014Q3': -2.46, '2014Q4': 2.44, '2015Q1': 5.44, '2015Q2': 5.46, '2015Q3': 5.46, '2015Q4': 5.46, '2016Q1': 3.87, '2016Q2': 3.17, '2016Q3': 3.87, '2016Q4': 3.88}}

和 df_line

{'GDP, nominal US$': {'2013Q1': -0.42, '2013Q2': 1.69, '2013Q3': 3.86, '2013Q4': 5.12, '2014Q1': 6.82, '2014Q2': 3.9, '2014Q3': 1.97, '2014Q4': 2.69, '2015Q1': 3.22, '2015Q2': 5.59, '2015Q3': 8.33, '2015Q4': 8.9, '2016Q1': 3.13, '2016Q2': 1.43, '2016Q3': 0.45, '2016Q4': 1.94}}

我分别制作了一个线图和一个簇柱形图,效果很好。

我尝试了以下方法

#Because dates are strings did this
dates_vals = list(df.index)
date_indices = np.arange(len(dates_vals))
x = np.arange(len(df))  # Numeric x-axis for plotting
X_2 = np.arange(len(df_line))


fig, ax = plt.subplots(figsize=(12, 8))

n_columns = len(df.columns) #as it is df I want to be columns 
# Width of a single bar
bar_width = 0.9 / n_columns

# Create bar containers
bars = []
for i, col in enumerate(df.columns):
    bar = ax.bar(x + i * bar_width, [0] * len(df), bar_width, label=col)
    bars.append(bar)

# Create the line plot with initial data set to NaNs to hide it initially
line, = ax.plot(X_2, [np.nan]*len(df_line), color="goldenrod", label=df_line.columns[0])


# Initialize function
def init():
    for bar in bars:
        for rect in bar:
            rect.set_height(0)
    line.set_ydata([np.nan]*len(df_line))  # Hide the line initially
    return [rect for bar in bars for rect in bar] + [line]

# Animate function
def animate(i):
    for j, bar in enumerate(bars):
        for k, rect in enumerate(bar):
            if k <= i:
                rect.set_height(df.iloc[k, j])
            else:
                rect.set_height(0)
    
    # Update the line data to show up to the current frame
    line.set_ydata(df_line.iloc[:i + 1].values.ravel())
    
    return [rect for bar in bars for rect in bar] + [line]


# Create the animation
ani = animation.FuncAnimation(
    fig, animate, init_func=init, frames=len(df), interval=50, blit=True, repeat=False
)



现在这确实有效了,但它的作用是从一开始就显示一条横跨所有 X 轴的实线,以及第一个 X 轴条目的两个条。然后一段时间内什么也没有发生,直到跳到最后一帧,这就是图表应有的样子。

如果我发现了一些明显的、动画图表方面的新内容,我深表歉意。

任何帮助将不胜感激。

python dataframe matplotlib animation charts
1个回答
0
投票

设法让它与以下内容一起工作,如果有人有类似的问题,我想会发布。

# Create bar containers
bars = []
for i, col in enumerate(df.columns):
    bar = ax.bar(x + i * bar_width, [0] * len(df), bar_width, label=col, color=Custom_Colours[i])
    bars.append(bar)

# Create the line plot with initial data set to NaNs to hide it initially
line, = ax.plot(x, [np.nan]*len(df_line), color="goldenrod", label=df_line.columns[0])



# Initialize function
def init():
    for bar in bars:
        for rect in bar:
            rect.set_height(0)
    line.set_ydata([np.nan] * len(df_line))  # Hide the line initially
    return [rect for bar in bars for rect in bar] + [line]

# Animate function
def animate(i):
    for j, bar in enumerate(bars):
        for k, rect in enumerate(bar):
            if k <= i:
                rect.set_height(df.iloc[k, j])
            else:
                rect.set_height(0)
    
    # Update the line data to show up to the current frame
    line.set_ydata(df_line.iloc[:i + 1])
    line.set_xdata(x[:i + 1])
    
    return [rect for bar in bars for rect in bar] + [line]


问题是我没有设置 x 数据

    line.set_xdata(x[:i + 1])

© www.soinside.com 2019 - 2024. All rights reserved.