在堆栈图的弹出窗口中打印图例
Print legend in popup for a stackplot
我正在尝试使用 python 使用 matplotlib 在堆栈图中绘制大量曲线。
要阅读图表,我需要显示图例,但如果我用 legend
方法显示它,我的图表将不可读(因为图例的数量及其大小)。
我发现 mplcursors
可以通过图表本身的弹出窗口帮助我做到这一点。它适用于 "simple" 图,但不适用于 stackplot
.
这是堆栈图的警告消息:
/usr/lib/python3.7/site-packages/mplcursors/_pick_info.py:141: UserWarning: Pick support for PolyCollection is missing.
warnings.warn(f"Pick support for {type(artist).__name__} is missing.")
这里是与此错误相关的代码(它只是一个概念证明):
import matplotlib.pyplot as plt
import mplcursors
import numpy as np
data = np.outer(range(10), range(1, 5))
timestamp = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
tmp = list()
tmp.append(data[:, 0])
tmp.append(data[:, 1])
tmp.append(data[:, 2])
tmp.append(data[:, 3])
print(data)
print(tmp)
fig, ax = plt.subplots()
ax.stackplot(timestamp, tmp, labels=('curve1', 'line2', 'curvefever', 'whatever'))
ax.legend()
mplcursors.cursor()
cursor = mplcursors.cursor(hover=True)
@cursor.connect("add")
def on_add(sel):
print(sel)
label = sel.artist.get_label()
sel.annotation.set(text=label)
plt.show()
您是否知道如何解决这个问题,或者您是否知道另一种方法来做类似的事情?
不清楚为什么 mplcursors 不接受堆栈图。但是您可以使用更原始的 matplotlib 功能复制行为:
import matplotlib.pyplot as plt
import numpy as np
def update_annot(label, x, y):
annot.xy = (x, y)
annot.set_text(label)
def on_hover(event):
visible = annot.get_visible()
is_outside_of_stackplot = True
if event.inaxes == ax:
for coll, label in zip(stckplt, labels):
contained, _ = coll.contains(event)
if contained:
update_annot(label, event.x, event.y)
annot.set_visible(True)
is_outside_of_stackplot = False
if is_outside_of_stackplot and visible:
annot.set_visible(False)
fig.canvas.draw_idle()
data = np.random.randint(1, 5, size=(4, 40))
fig, ax = plt.subplots()
labels = ('curve1', 'line2', 'curvefever', 'whatever')
stckplt = ax.stackplot(range(data.shape[1]), data, labels=labels)
ax.autoscale(enable=True, axis='x', tight=True)
# ax.legend()
annot = ax.annotate("", xy=(0, 0), xycoords="figure pixels",
xytext=(20, 20), textcoords="offset points",
bbox=dict(boxstyle="round", fc="yellow", alpha=0.6),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
plt.connect('motion_notify_event', on_hover)
plt.show()
我正在尝试使用 python 使用 matplotlib 在堆栈图中绘制大量曲线。
要阅读图表,我需要显示图例,但如果我用 legend
方法显示它,我的图表将不可读(因为图例的数量及其大小)。
我发现 mplcursors
可以通过图表本身的弹出窗口帮助我做到这一点。它适用于 "simple" 图,但不适用于 stackplot
.
这是堆栈图的警告消息:
/usr/lib/python3.7/site-packages/mplcursors/_pick_info.py:141: UserWarning: Pick support for PolyCollection is missing.
warnings.warn(f"Pick support for {type(artist).__name__} is missing.")
这里是与此错误相关的代码(它只是一个概念证明):
import matplotlib.pyplot as plt
import mplcursors
import numpy as np
data = np.outer(range(10), range(1, 5))
timestamp = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
tmp = list()
tmp.append(data[:, 0])
tmp.append(data[:, 1])
tmp.append(data[:, 2])
tmp.append(data[:, 3])
print(data)
print(tmp)
fig, ax = plt.subplots()
ax.stackplot(timestamp, tmp, labels=('curve1', 'line2', 'curvefever', 'whatever'))
ax.legend()
mplcursors.cursor()
cursor = mplcursors.cursor(hover=True)
@cursor.connect("add")
def on_add(sel):
print(sel)
label = sel.artist.get_label()
sel.annotation.set(text=label)
plt.show()
您是否知道如何解决这个问题,或者您是否知道另一种方法来做类似的事情?
不清楚为什么 mplcursors 不接受堆栈图。但是您可以使用更原始的 matplotlib 功能复制行为:
import matplotlib.pyplot as plt
import numpy as np
def update_annot(label, x, y):
annot.xy = (x, y)
annot.set_text(label)
def on_hover(event):
visible = annot.get_visible()
is_outside_of_stackplot = True
if event.inaxes == ax:
for coll, label in zip(stckplt, labels):
contained, _ = coll.contains(event)
if contained:
update_annot(label, event.x, event.y)
annot.set_visible(True)
is_outside_of_stackplot = False
if is_outside_of_stackplot and visible:
annot.set_visible(False)
fig.canvas.draw_idle()
data = np.random.randint(1, 5, size=(4, 40))
fig, ax = plt.subplots()
labels = ('curve1', 'line2', 'curvefever', 'whatever')
stckplt = ax.stackplot(range(data.shape[1]), data, labels=labels)
ax.autoscale(enable=True, axis='x', tight=True)
# ax.legend()
annot = ax.annotate("", xy=(0, 0), xycoords="figure pixels",
xytext=(20, 20), textcoords="offset points",
bbox=dict(boxstyle="round", fc="yellow", alpha=0.6),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
plt.connect('motion_notify_event', on_hover)
plt.show()