Изменить цвет маркера в легенде matplotlib? - PullRequest
1 голос
/ 17 октября 2019

Код для этого примера в основном взят из Маркер разделения и строки в легенде - Matplotlib - за исключением того, что я добавил взаимодействие для переключения легенды из https://matplotlib.org/3.1.1/gallery/event_handling/legend_picking.html

Этокак выглядит поведение:

Figure_1

Давайте на время пока проигнорируем логику переключения реальных линий графика.

Моя проблема здесь в том, что когда я нажимаю на записи в легенде, которые являются только маркерами - они НЕ меняют ни альфа, ни цвет - даже если я использовал set_markerfacecolor() специально, чтобы заставить их цвет.

С другой стороны, когда я нажимаю на записи в легенде, которые являются только строками, они без проблем меняют альфу.

Итак, как я могу получить маркеры на легенде, чтобытакже изменить альфа (или цвет) при нажатии / выборе / переключении?

Распечатки, которые я получаю в терминале за первые несколько нажатий на анимированном GIF:

$ python3 /tmp/test3.py
(0.0, 0.0, 0.0, 1)
(0.2, 0.2, 0.2, 0.2)
(1.0, 1.0, 1.0, 1.0)
(0.2, 0.2, 0.2, 0.2)
(0.0, 0.0, 0.0, 1)
(0.2, 0.2, 0.2, 0.2)
(1.0, 1.0, 1.0, 1.0)
(0.2, 0.2, 0.2, 0.2)
(0.0, 0.0, 0.0, 1)
(0.2, 0.2, 0.2, 0.2)
(1.0, 1.0, 1.0, 1.0)
(0.2, 0.2, 0.2, 0.2)
(0.0, 0.0, 1.0, 1)
(0.2, 0.2, 0.2, 0.2)
...

Код:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import colors

def function_to_split(hand,labl,dividor):

    Hand_L=[]
    Hand_M=[]
    Labl_L=[]
    Labl_M=[]

    for h,l in zip(hand,labl):
        co=h.get_color()
        ls=h.get_linestyle()
        lw=h.get_linewidth()
        mk=h.get_marker()
        mew=h.get_markeredgewidth()
        ms=h.get_markersize()

        LABS=l.split(dividor)

        if len(LABS) != 2:
            print('Split Legends Error: Only exactly 1 Dividor is accepted.')
            print('                     Currently ' + str(len(LABS)-1) + ' dividors were given')
            return hand,labl

        #Line and Color
        LICO = plt.Line2D((0,1),(0,0), color=co, marker='', linestyle=ls,linewidth=lw)
        #Marker
        MARK = plt.Line2D((0,1),(0,0), color='k', marker=mk, markeredgewidth=mew, markersize=ms, linestyle='')

        if LABS[0] not in Labl_L:
            Hand_L.append(LICO)
            Labl_L.append(LABS[0])

        if LABS[1] not in Labl_M:
            Hand_M.append(MARK)
            Labl_M.append(LABS[1])

    return Hand_L+Hand_M,Labl_L+Labl_M



pi=3.14
xx=np.linspace(0,2*pi,100)


fig = plt.figure()
ax  = fig.add_subplot(111)

phases=[0,pi/4,pi/2]
markers=['s','o','^']

lines = []
for phase,mk in zip(phases,markers):
    labeltext='Sine' + '*' + str(phase)
    F=[np.sin(x+phase) for x in xx]
    line, = ax.plot(xx,F,color='b',marker=mk,label=labeltext)
    lines.append(line)

    labeltext='Cosine' + '*' + str(phase)
    F=[np.cos(x+phase) for x in xx]
    line, = ax.plot(xx,F,color='g',marker=mk,label=labeltext)
    lines.append(line)

hand, labl = ax.get_legend_handles_labels()
hand, labl = function_to_split(hand,labl,'*')
leg = ax.legend(hand,labl)
#plt.savefig('Figure.png')

# https://matplotlib.org/3.1.1/gallery/event_handling/legend_picking.html
lined = dict()

for legline, origline in zip(leg.get_lines(), lines):
    legline.set_picker(5)  # 5 pts tolerance
    lined[legline] = origline

# NOTE: in the legend, can just click on line to trigger onpick()
# however, clicking on standalone marker in legend won't trigger,
# so you have to click in the whitespace around the legend marker to trigger onpick()!
def onpick(event):
    # on the pick event, find the orig line corresponding to the
    # legend proxy line, and toggle the visibility
    legline = event.artist
    origline = lined[legline]
    vis = not origline.get_visible()
    origline.set_visible(vis)
    # Change the alpha on the line in the legend so we can see what lines
    # have been toggled
    # NB: .set_alpha() works only on lines, not on markers!
    mfcol = colors.to_rgba(legline.get_markerfacecolor())
    print(mfcol)
    if vis:
        legline.set_markerfacecolor( (1.0, 1.0, 1.0, 1.0) )
        legline.set_alpha(1.0)
    else:
        legline.set_markerfacecolor( (0.2, 0.2, 0.2, 0.2) )
        legline.set_alpha(0.2)
    fig.canvas.draw()

fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...