我正在尝试制作一个逐帧更新的动画图表,以使最终结果对于每个 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 轴条目的两个条。然后一段时间内什么也没有发生,直到跳到最后一帧,这就是图表应有的样子。
如果我发现了一些明显的、动画图表方面的新内容,我深表歉意。
任何帮助将不胜感激。
设法让它与以下内容一起工作,如果有人有类似的问题,我想会发布。
# 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])