matplotlib(mpl_connect) 在 for 循环中创建许多交互式图不起作用
matplotlib(mpl_connect) in for loop to create many interactive plots does not work
我有一个 for 循环生成不同的数据帧 (pandas) 然后绘制它。
我想创建许多交互式图表,以便我可以在图表中显示和隐藏不同的线条。
为此,我正在使用 on_pick 函数(如前所述 )
问题是,当我绘制一个 table 时,它有效并且我有交互式图例,但是当我尝试在 for 循环中绘制多个图表时,没有一个图例是交互式的。
df = pd.DataFrame(np.array([[0.45,0.12,0.66,0.76,0.22],[0.22,0.24,0.12,0.56,0.34],[0.12,0.47,0.93,0.65,0.21]]),
columns=[60.1,65.5,67.3,74.2,88.5])
df['name']=['A1','B4','B7']
df=df.set_index('name')
#plot alone:
fig, ax = plt.subplots()
df.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
lined = {} # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
lined[legline] = origline
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
结果:我可以启用和禁用图例中的线条的图:
#plot many plots in for loop:
nums=[5,8,0.3]
for n in nums:
db=df*n
fig, ax = plt.subplots()
db.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
lined = {} # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
lined[legline] = origline
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
结果:我得到了情节,但无法播放将显示的线条。
*当我触摸线条时,它仍然以交互方式显示 x 和 y 值,但图例不是交互式的。
我的最终目标:在 matplotlib 中的 for 循环中生成多个交互式绘图,并能够启用和禁用图例项。
您可以使用 PyQT5 制作多个动态实时图表
https://eli.thegreenplace.net/2009/05/23/more-pyqt-plotting-demos
以下是同时显示它们的方法,使用 fig
作为 lined
的载体
多个独立地块
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame(np.array([[0.45,0.12,0.66,0.76,0.22],[0.22,0.24,0.12,0.56,0.34],[0.12,0.47,0.93,0.65,0.21]]),
columns=[60.1,65.5,67.3,74.2,88.5])
df['name']=['A1','B4','B7']
df=df.set_index('name')
#plot many plots in for loop:
nums=[5,8,0.3]
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = event.canvas.figure.lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
event.canvas.draw()
for n in nums:
db=df*n
fig, ax = plt.subplots()
db.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
fig.lined = {} # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
fig.lined[legline] = origline
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
使用子图
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame(np.array([[0.45,0.12,0.66,0.76,0.22],[0.22,0.24,0.12,0.56,0.34],[0.12,0.47,0.93,0.65,0.21]]),
columns=[60.1,65.5,67.3,74.2,88.5])
df['name']=['A1','B4','B7']
df=df.set_index('name')
#plot many plots in for loop:
nums=[5,8,0.3]
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = event.canvas.figure.lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
event.canvas.draw()
nrows = int(np.ceil(np.sqrt(len(nums))))
ncols = int(np.ceil(len(nums) / nrows))
fig, axs = plt.subplots(nrows=nrows,ncols=ncols)
if not isinstance(axs,np.ndarray):
axs = np.array([[axs]])
if len(axs.shape)==1:
axs = np.expand_dims(axs,axis=1)
fig.lined = {} # Will map legend lines to original lines.
for idx,n in enumerate(nums):
db=df*n
ax = axs[int(idx/ncols),idx % ncols]
db.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
fig.lined[legline] = origline
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
我有一个 for 循环生成不同的数据帧 (pandas) 然后绘制它。
我想创建许多交互式图表,以便我可以在图表中显示和隐藏不同的线条。
为此,我正在使用 on_pick 函数(如前所述
问题是,当我绘制一个 table 时,它有效并且我有交互式图例,但是当我尝试在 for 循环中绘制多个图表时,没有一个图例是交互式的。
df = pd.DataFrame(np.array([[0.45,0.12,0.66,0.76,0.22],[0.22,0.24,0.12,0.56,0.34],[0.12,0.47,0.93,0.65,0.21]]),
columns=[60.1,65.5,67.3,74.2,88.5])
df['name']=['A1','B4','B7']
df=df.set_index('name')
#plot alone:
fig, ax = plt.subplots()
df.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
lined = {} # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
lined[legline] = origline
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
结果:我可以启用和禁用图例中的线条的图:
#plot many plots in for loop:
nums=[5,8,0.3]
for n in nums:
db=df*n
fig, ax = plt.subplots()
db.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
lined = {} # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
lined[legline] = origline
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
结果:我得到了情节,但无法播放将显示的线条。
*当我触摸线条时,它仍然以交互方式显示 x 和 y 值,但图例不是交互式的。
我的最终目标:在 matplotlib 中的 for 循环中生成多个交互式绘图,并能够启用和禁用图例项。
您可以使用 PyQT5 制作多个动态实时图表 https://eli.thegreenplace.net/2009/05/23/more-pyqt-plotting-demos
以下是同时显示它们的方法,使用 fig
作为 lined
多个独立地块
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame(np.array([[0.45,0.12,0.66,0.76,0.22],[0.22,0.24,0.12,0.56,0.34],[0.12,0.47,0.93,0.65,0.21]]),
columns=[60.1,65.5,67.3,74.2,88.5])
df['name']=['A1','B4','B7']
df=df.set_index('name')
#plot many plots in for loop:
nums=[5,8,0.3]
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = event.canvas.figure.lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
event.canvas.draw()
for n in nums:
db=df*n
fig, ax = plt.subplots()
db.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
fig.lined = {} # Will map legend lines to original lines.
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
fig.lined[legline] = origline
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()
使用子图
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame(np.array([[0.45,0.12,0.66,0.76,0.22],[0.22,0.24,0.12,0.56,0.34],[0.12,0.47,0.93,0.65,0.21]]),
columns=[60.1,65.5,67.3,74.2,88.5])
df['name']=['A1','B4','B7']
df=df.set_index('name')
#plot many plots in for loop:
nums=[5,8,0.3]
def on_pick(event):
#On the pick event, find the original line corresponding to the legend
#proxy line, and toggle its visibility.
legline = event.artist
origline = event.canvas.figure.lined[legline]
visible = not origline.get_visible()
origline.set_visible(visible)
#Change the alpha on the line in the legend so we can see what lines
#have been toggled.
legline.set_alpha(1.0 if visible else 0.2)
event.canvas.draw()
nrows = int(np.ceil(np.sqrt(len(nums))))
ncols = int(np.ceil(len(nums) / nrows))
fig, axs = plt.subplots(nrows=nrows,ncols=ncols)
if not isinstance(axs,np.ndarray):
axs = np.array([[axs]])
if len(axs.shape)==1:
axs = np.expand_dims(axs,axis=1)
fig.lined = {} # Will map legend lines to original lines.
for idx,n in enumerate(nums):
db=df*n
ax = axs[int(idx/ncols),idx % ncols]
db.T.plot(ax=ax)
lines = ax.get_lines()
leg = ax.legend(fancybox=True, shadow=True)
for legline, origline in zip(leg.get_lines(), lines):
legline.set_picker(True) # Enable picking on the legend line.
fig.lined[legline] = origline
fig.canvas.mpl_connect('pick_event', on_pick)
plt.show()