Отображать текст аннотации сюжета одновременно в matplotlib - PullRequest
1 голос
/ 13 февраля 2020

Я пытаюсь отобразить текст аннотации для нескольких графиков на одном графике (или рисунке) одновременно. Приведенный ниже код работает отлично, но он отображает одну аннотацию для одного графика за раз, но мой график имеет несколько графиков. plot1_list, plot2_list, plot3_list - это списки графиков на моем графике. Тексты аннотаций представлены в виде «ярлыков» на моих графиках. Как я могу отобразить текст аннотации для каждого графика в каждом списке одновременно?

import mplcursors



cursor1 = mplcursors.cursor(plot1_list, hover=False, bindings={"toggle_visible": "h", "toggle_enabled": "e"})
@cursor1.connect("add")
def on_add(sel):
    sel.annotation.set_text(sel.artist.get_label())

cursor2 = mplcursors.cursor(plot2_list, hover=False, bindings={"toggle_visible": "h", "toggle_enabled": "e"})
@cursor2.connect("add")
def on_add(sel):
    sel.annotation.set_text(sel.artist.get_label())

cursor3 = mplcursors.cursor(plot3_list, hover=False, bindings={"toggle_visible": "h", "toggle_enabled": "e"})
@cursor3.connect("add")
def on_add(sel):
    sel.annotation.set_text(sel.artist.get_label())

Список графиков в приведенном выше коде создается с использованием кода ниже:

label1 = str("MAXIMUM HEAD=" + str(m_head))
label2 = str("MAXIMUM POWER=" + str(m_power))
label3 = str("MAXIMUM EFFICIENCY=" + str(m_efficiency))

plot1, = host.plot(y0, y, linestyle=styles[0], color=colorstouse[count], label=label1)
plot2, = par1.plot(y0, y1, linestyle=styles[1], color=colorstouse[count], label=label2)
plot3, = par2.plot(y0, y2, linestyle=styles[2], color=colorstouse[count], label=label3)

Attached is the image of a sample plot

1 Ответ

1 голос
/ 13 февраля 2020

В вашем случае вам понадобится отдельный mplcursor для каждой кривой. Таким образом, каждый из них может быть индивидуально включен или выключен.

Код выглядит немного сложнее, чем необходимо. Вот попытка упростить. В примере показаны 15 кривых с использованием 3 осей. Обратите внимание, что он может стать очень переполненным, поэтому 90 кривых может быть слишком много.

from matplotlib import pyplot as plt
import numpy as np
import mplcursors

num_devices = 5
fig, host = plt.subplots(figsize=(12, 4))
fig.subplots_adjust(right=0.8)

par1 = host.twinx()
par2 = host.twinx()
par2.spines["right"].set_position(("axes", 1.1))

x = np.linspace(0, 10)
y = -x ** 2 + 5 * x + 10
y1 = 10 + 20 * np.cos(x)
y2 = 30 + 5 * np.sin(x)

ys = [y + np.random.uniform(10, 30) for i in range(num_devices)]
y1s = [y1 + np.random.uniform(10, 30) for i in range(num_devices)]
y2s = [y2 + np.random.uniform(10, 30) for i in range(num_devices)]

colors = plt.cm.tab10.colors
plots = []
for dev in range(num_devices):
    plot1 = host.plot(x, ys[dev], c=colors[dev], ls='-', label=f'plot 1 - dev {dev}')
    plot2, = par1.plot(x, y1s[dev], c=colors[dev], ls='--', label=f'plot 2 - dev {dev}')
    plot3, = par2.plot(x, y2s[dev], c=colors[dev], ls=':', label=f'plot 3 - dev {dev}')
    plots += [plot1, plot2, plot3]

print(plots)
for i, plot in enumerate(plots):
    cursor = mplcursors.cursor(plot, hover=False, bindings={"toggle_visible": "h", "toggle_enabled": "e"})
    cursor.connect("add", lambda sel: sel.annotation.set_text(sel.artist.get_label()))
plt.show()

sample plot

...