[英]Matplotlib - Implement multiple y-axis scales in animated line graph
I'm trying to remake an existing animated line graph I made where each line has a uniquely scaled y-axis - one on the left, one on the right.我正在尝试重新制作我制作的现有动画线图,其中每条线都有一个独特缩放的 y 轴- 一条在左边,一条在右边。 The graph is comparing the value of two cryptocurrencies that have vastly different sizes (eth/btc), which is why I need multiple scales to actually see changes.
该图比较了两种大小差异很大的加密货币 (eth/btc) 的价值,这就是为什么我需要多个尺度才能真正看到变化。
My data has been formatted in a pd df (numbers here are random):我的数据已经格式化为 pdf df(这里的数字是随机的):
Date ETH Price BTC Price
0 2020-10-30 00:00:00 0.155705 1331.878496
1 2020-10-31 00:00:00 0.260152 1337.174272
.. ... ... ...
290 2021-08-15 16:42:09 0.141994 2846.719819
[291 rows x 3 columns]
And code is roughly:代码大致是:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
color = ['cyan', 'orange', 'red']
fig = plt.figure()
plt.xticks(rotation=45, ha="right", rotation_mode="anchor")
plt.subplots_adjust(bottom = 0.2, top = 0.9)
plt.ylabel('Coin Value (USD)')
plt.xlabel('Date')
def buildChart(i=int):
df1 = df.set_index('Date', drop=True)
plt.legend(["ETH Price", "BTC Price"])
p = plt.plot(df1[:i].index, df1[:i].values)
for i in range(0,2):
p[i].set_color(color[i])
animator = ani.FuncAnimation(fig, buildChart, interval = 10)
plt.show()
Resulting Animation结果 Animation
I tried to create a second axis with a twin x to the first axis.我试图创建第二个轴,其中双 x 到第一个轴。
color = ['cyan', 'orange', 'blue']
fig, ax1 = plt.subplots() #Changes over here
plt.xticks(rotation=45, ha="right", rotation_mode="anchor")
plt.subplots_adjust(bottom = 0.2, top = 0.9)
plt.ylabel('Coin Value (USD)')
plt.xlabel('Date')
def buildChart(i=int):
df1 = df.set_index('Date', drop=True)
plt.legend(["ETH Price", "Bitcoin Price"])
data1 = df1.iloc[:i, 0:1] # Changes over here
# ------------- More Changes Start
ax2 = ax1.twinx()
ax2.set_ylabel('Cost of Coin (USD)')
data2 = df1.iloc[:i, 1:2]
ax2.plot(df1[:i].index, data2)
ax2.tick_params(axis='y')
# -------------- More Changes End
p = plt.plot(df1[:i].index, data1)
for i in range(0,1):
p[i].set_color(color[i])
import matplotlib.animation as ani
animator = ani.FuncAnimation(fig, buildChart, interval = 10)
plt.show()
Resulting Animation After Changes修改后得到 Animation
Current issues:当前的问题:
I believe my approach to making a second scale must have been wrong to get this many errors, but this seems like the way to do it.我相信我制作第二个秤的方法一定是错误的,才会出现这么多错误,但这似乎是这样做的方法。
I re-structured your code in order to easily set up a secondary axis animation.我重新构建了您的代码,以便轻松设置辅助轴 animation。
Here the code of the animation with a single y axis:这是带有单个 y 轴的 animation 的代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
df = pd.DataFrame({'date': pd.date_range(start = '2020-01-01', end = '2020-04-01', freq = 'D')})
df['ETH'] = 2*df.index + 300 + 100*np.random.randn(len(df))
df['BTC'] = 5*df.index + 13000 + 200*np.random.randn(len(df))
def update(i):
ax.cla()
ax.plot(df.loc[:i, 'date'], df.loc[:i, 'ETH'], label = 'ETH Price', color = 'red')
ax.plot(df.loc[:i, 'date'], df.loc[:i, 'BTC'], label = 'BTC Price', color = 'blue')
ax.legend(frameon = True, loc = 'upper left', bbox_to_anchor = (1.15, 1))
ax.set_ylim(0.9*min(df['ETH'].min(), df['BTC'].min()), 1.1*max(df['ETH'].max(), df['BTC'].max()))
ax.tick_params(axis = 'x', which = 'both', top = False)
ax.tick_params(axis = 'y', which = 'both', right = False)
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 45)
ax.set_xlabel('Date')
ax.set_ylabel('ETH Coin Value (USD)')
plt.tight_layout()
fig, ax = plt.subplots(figsize = (6, 4))
ani = FuncAnimation(fig = fig, func = update, frames = len(df), interval = 100)
plt.show()
Starting from the code above, you should twin the axis out of the update
function: if you keep ax.twinx()
inside the function, this operation will be repeated in each iteration and you will get a new axis each time.从上面的代码开始,您应该将轴从
update
function 中分离出来:如果您将ax.twinx()
保留在 function 中,则每次迭代都会重复此操作,并且每次都会获得一个新轴。
Below the code for an animation with a secondary axis:在带有辅助轴的 animation 的代码下方:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
df = pd.DataFrame({'date': pd.date_range(start = '2020-01-01', end = '2020-04-01', freq = 'D')})
df['ETH'] = 2*df.index + 300 + 100*np.random.randn(len(df))
df['BTC'] = 5*df.index + 13000 + 200*np.random.randn(len(df))
def update(i):
ax1.cla()
ax2.cla()
line1 = ax1.plot(df.loc[:i, 'date'], df.loc[:i, 'ETH'], label = 'ETH Price', color = 'red')
line2 = ax2.plot(df.loc[:i, 'date'], df.loc[:i, 'BTC'], label = 'BTC Price', color = 'blue')
lines = line1 + line2
labels = [line.get_label() for line in lines]
ax1.legend(lines, labels, frameon = True, loc = 'upper left', bbox_to_anchor = (1.15, 1))
ax1.set_ylim(0.9*df['ETH'].min(), 1.1*df['ETH'].max())
ax2.set_ylim(0.9*df['BTC'].min(), 1.1*df['BTC'].max())
ax1.tick_params(axis = 'x', which = 'both', top = False)
ax1.tick_params(axis = 'y', which = 'both', right = False, colors = 'red')
ax2.tick_params(axis = 'y', which = 'both', right = True, labelright = True, left = False, labelleft = False, colors = 'blue')
plt.setp(ax1.xaxis.get_majorticklabels(), rotation = 45)
ax1.set_xlabel('Date')
ax1.set_ylabel('ETH Coin Value (USD)')
ax2.set_ylabel('BTC Coin Value (USD)')
ax1.yaxis.label.set_color('red')
ax2.yaxis.label.set_color('blue')
ax2.spines['left'].set_color('red')
ax2.spines['right'].set_color('blue')
plt.tight_layout()
fig, ax1 = plt.subplots(figsize = (6, 4))
ax2 = ax1.twinx()
ani = FuncAnimation(fig = fig, func = update, frames = len(df), interval = 100)
plt.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.