我正在尝试制作一个逐帧更新的动画图表,以使最终结果的每个 x 轴条目有两列(在年份或年份和 Q 之间确实有所不同,但无论哪种方式都是字符串)和一条线。|| |我有两个数据框,在这种情况下我读到了帮助。
df
和 df_line
{'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}}
我分别制作了一个线图和一个簇柱形图,效果很好。
{'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}}
我尝试了下面
现在这确实有效,但它的作用是从一开始就显示一条横跨所有 X 轴的实线,以及第一个 X 轴条目的两个条。然后一段时间什么也没有发生,直到它跳到最后一帧,这就是图表应有的样子。
#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
)
如果我看到了一些明显的、动画图表的新东西,我深表歉意。
任何帮助将不胜感激。
Any help would be greatly appreciated.
以下是使用 matplotlib 为簇状柱形图和折线图创建动画的改进方法:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import pandas as pd
import numpy as np
# Your data
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}}
df = pd.DataFrame(df)
df_line = pd.DataFrame(df_line)
# Create the figure and axes
fig, ax = plt.subplots(figsize=(12, 8))
# Number of bars per x-tick
n_columns = len(df.columns)
# Width of each bar
bar_width = 0.9 / n_columns
# Create bar containers
bars = []
for i, col in enumerate(df.columns):
bar = ax.bar(np.arange(len(df)) + i * bar_width, [0] * len(df), bar_width, label=col)
bars.append(bar)
# Create the line plot
line, = ax.plot([], [], color="goldenrod", label=df_line.columns[0])
# Set x-axis ticks and labels
ax.set_xticks(np.arange(len(df)) + bar_width * (n_columns - 1) / 2) # Center x-ticks
ax.set_xticklabels(df.index)
# Add a legend
ax.legend()
# Function to initialize the animation
def init():
for bar in bars:
for rect in bar:
rect.set_height(0)
line.set_data([], []) # Initialize line data to empty
return bars + [line]
# Function to update the animation for each frame
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)
line.set_data(df_line.index[:i+1], df_line.iloc[:i+1].values.ravel())
return bars + [line]
# Create the animation
ani = animation.FuncAnimation(
fig, animate, frames=len(df), init_func=init, interval=50, blit=True
)
plt.show()
以下是代码改进之处:
-
数据处理:
使用提供的字典创建了
pandas DataFrame
,以便于数据操作。 -
x 轴标签:
调整了
xticks
的位置,以便它们位于柱状图组的中心。 -
动画函数:
简化了
animate
函数,直接更新柱状图的高度和线条的数据,而不是先将其设置为NaN
。 -
init
函数: 修改了init
函数,将线条数据初始化为空列表,以便在动画开始时线条不可见。
这些更改将创建一个动画,该动画平滑地从左到右构建图表,首先显示数据的第一帧,然后逐帧添加更多数据,直到显示完整图表。
标签:python,dataframe,matplotlib,animation,charts From: 78821389