我有一组地块,分布在两个网格中。在左侧网格中,顶部有一个图(整个宽度),底部有两个图(并排)。底部的两个共享图例。在我的右侧网格中,我想要图例,它是很多数据系列,并且我希望使用图形的整个高度。
数据系列的外观具有动画效果,但我希望不要出现图例。
我的想法是在带有图例的右侧网格中绘制时间序列,然后隐藏数据序列。但是我唯一的解决方案是ax.set_visible(False),它将删除所有内容。
这主要是脚本的外观(简化版):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as anim
from matplotlib.gridspec import GridSpec
data = np.array([[1],[2],[3],[4]])
sett = np.array([1,2,3,4])
data1 = np.hstack((data,data*2, data*3, data*4))
data2 = np.hstack((3*data, 3*data/2, 3*data/3, 3*data/4))
df1 = pd.DataFrame(data = np.array(data1), index = [1,2,3,4], columns =
sett).transpose()
df2 = pd.DataFrame(data = np.array(data2), index = [1,2,3,4], columns =
sett).transpose()
gs1 = GridSpec(2,2)
gs1.update(left=0.05, right = 0.80, hspace = 0.05)
gs2 = GridSpec(3,1)
gs2.update(left=0.85, right = 0.98, hspace = 0.05)
figure = plt.figure()
plt.clf()
ax1 = plt.subplot(gs1[0,:])
ax2 = plt.subplot(gs1[1,0])
ax3 = plt.subplot(gs1[1,1], sharey = ax2)
ax4 = plt.subplot(gs2[:,0])
ax1.set_ylim(0,25)
label = ['s0', 's1', 's2', 's3', 's4']
ax4.plot(df1[1], df2[:])
ax4.legend(labels = label)
def make_frame(i):
ct=sett[i]
ax2.plot(df1[1], df1[ct])
ax3.plot(df1[1], df2[ct])
ax3.legend(labels = label)
ani = anim.FuncAnimation(figure, make_frame, frames = len(sett),
interval =500, repeat = False)
plt.show()
如何删除数据系列并将图例保留在gs2 / ax4中?
不要打扰我在ax2和ax3中两次绘制第一个数据系列-在我的原始脚本中没关系。但是-如果有人可以启发我为什么这样做,我们将不胜感激。
答案 0 :(得分:0)
我不太确定所需的输出是什么。您是否要立即将图例放在ax4
的位置,但目前没有在ax4
中显示的情节。
我的解决方案是根本不创建ax4
。相反,您可以使用bbox_to_anchor
移动图例的位置。在这里,我使用从ax1
开始的变换来建立相对于ax1
的位置,然后将图例稍微移到ax1
的右边缘和顶部。
请参见"legend guide" for more information。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as anim
from matplotlib.gridspec import GridSpec
data = np.array([[1], [2], [3], [4]])
sett = np.array([1, 2, 3, 4])
data1 = np.hstack((data, data * 2, data * 3, data * 4))
data2 = np.hstack((3 * data, 3 * data / 2, 3 * data / 3, 3 * data / 4))
df1 = pd.DataFrame(data=np.array(data1), index=[1, 2, 3, 4], columns=sett).transpose()
df2 = pd.DataFrame(data=np.array(data2), index=[1, 2, 3, 4], columns=sett).transpose()
gs1 = GridSpec(2, 2)
gs1.update(left=0.05, right=0.80, hspace=0.05)
figure = plt.figure()
plt.clf()
ax1 = plt.subplot(gs1[0, :])
ax2 = plt.subplot(gs1[1, 0])
ax3 = plt.subplot(gs1[1, 1], sharey=ax2)
label = ['s0', 's1', 's2', 's3', 's4']
def make_frame(i):
ct = sett[i]
ax2.plot(df1[1], df1[ct])
ax3.plot(df1[1], df2[ct])
ax3.legend(labels=label, loc='upper left', bbox_to_anchor=(1.05, 1.), bbox_transform=ax1.transAxes)
ani = anim.FuncAnimation(figure, make_frame, frames=len(sett),
interval=500, repeat=False)
plt.show()
编辑:在动画开始之前使用proxy artist创建所有图例
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as anim
from matplotlib.gridspec import GridSpec
data = np.array([[1], [2], [3], [4]])
sett = np.array([1, 2, 3, 4])
data1 = np.hstack((data, data * 2, data * 3, data * 4))
data2 = np.hstack((3 * data, 3 * data / 2, 3 * data / 3, 3 * data / 4))
df1 = pd.DataFrame(data=np.array(data1), index=[1, 2, 3, 4], columns=sett).transpose()
df2 = pd.DataFrame(data=np.array(data2), index=[1, 2, 3, 4], columns=sett).transpose()
gs1 = GridSpec(2, 2)
gs1.update(left=0.05, right=0.80, hspace=0.05)
figure = plt.figure()
plt.clf()
ax1 = plt.subplot(gs1[0, :])
ax2 = plt.subplot(gs1[1, 0])
ax3 = plt.subplot(gs1[1, 1], sharey=ax2)
ax1.set_ylim(0, 25)
labels = ['s0', 's1', 's2', 's3', 's4']
colors = ['C0', 'C1', 'C2', 'C3', 'C4']
proxies = [plt.plot([], [], c=c)[0] for c in colors]
ax1.legend(proxies, labels, bbox_to_anchor=(1., 1.), loc="upper left")
def init_frame():
pass
def make_frame(i):
ct = sett[i]
ax2.plot(df1[1], df1[ct], c=colors[i], label=labels[i])
ax3.plot(df1[1], df2[ct], c=colors[i], label=labels[i])
ax3.legend()
ani = anim.FuncAnimation(figure, make_frame, init_func=init_frame, frames=len(sett),
interval=500, repeat=False)
plt.show()
答案 1 :(得分:0)
我将在制作动画之前创建折线图。您可以使用空列表初始化它们,然后一一设置数据。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as anim
from matplotlib.gridspec import GridSpec
data = np.array([1,2,3,4,5])
data1 = np.vstack((data,data*2, data*3, data*4))
data2 = np.vstack((3*data, 3*data/2, 3*data/3, 3*data/4))
df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)
sett = np.arange(len(df1.columns))
gs1 = GridSpec(2,2)
gs1.update(left=0.05, right = 0.80, hspace = 0.05)
figure = plt.figure()
ax1 = plt.subplot(gs1[0,:])
ax2 = plt.subplot(gs1[1,0])
ax3 = plt.subplot(gs1[1,1], sharey = ax2, sharex= ax2)
ax2.set_ylim(0,25)
lines1 = ax2.plot(*[[] for _ in range(len(sett)*2)])
lines2 = ax3.plot(*[[] for _ in range(len(sett)*2)])
label = ['s0', 's1', 's2', 's3', 's4']
ax1.legend(handles = lines1, labels=label, bbox_to_anchor=(1.05,1), loc="upper left")
def init():
for line in lines1+lines2:
line.set_data([],[])
def make_frame(i):
ct=sett[i]
lines1[i].set_data(df1.index, df1[ct])
lines2[i].set_data(df1.index, df2[ct])
ax2.relim()
ax2.autoscale_view()
ani = anim.FuncAnimation(figure, make_frame, init_func=init, frames = len(sett),
interval =500, repeat = False)
ani.save("anigif.gif", writer="imagemagick")
plt.show()