Установить прозрачность символа легенды с помощью matplotlib?

Я работаю над сюжетом с полупрозрачными маркерами "x" (20% альфа). Как сделать маркер в 100% непрозрачности в легенде?

import matplotlib.pyplot as plt
plt.plot_date( x = xaxis, y = yaxis, marker = 'x', color=[1, 0, 0, .2], label='Data Series' )
plt.legend(loc=3, mode="expand", numpoints=1, scatterpoints=1 )

Ответы

Ответ 1

Если вы хотите иметь что-то конкретное в своей легенде, проще определить объекты, которые вы помещаете в легенде, с соответствующим текстом. Например:

import matplotlib.pyplot as plt
import pylab

plt.plot_date( x = xaxis, y = yaxis, marker = 'x', color=[1, 0, 0, .2], label='Data Series' )
line1 = pylab.Line2D(range(1),range(1),color='white',marker='x',markersize=10, markerfacecolor="red",alpha=1.0)
line2 = pylab.Line2D(range(10),range(10),marker="_",linewidth=3.0,color="dodgerblue",alpha=1.0)
plt.legend((line1,line2),('Text','Other Text'),numpoints=1,loc=1)

Здесь строка 1 определяет короткую, белую линию (настолько невидимую) с маркером 'x' в красном и полном непрозрачности. Например, строка 2 дает вам более длинную синюю линию без видимых маркеров. Создавая эти "строки", вы можете более легко контролировать свои свойства в легенде.

Ответ 2

Следя за ответом космоса, чтобы сделать "поддельные" строки для легенды невидимыми на сюжете, вы можете использовать NaN, и они все равно будут работать для генерации записей легенды:

import numpy as np
import matplotlib.pyplot as plt
# Plot data with alpha=0.2
plt.plot((0,1), (0,1), marker = 'x', color=[1, 0, 0, .2])
# Plot non-displayed NaN line for legend, leave alpha at default of 1.0
legend_line_1 = plt.plot( np.NaN, np.NaN, marker = 'x', color=[1, 0, 0], label='Data Series' )
plt.legend()

Ответ 3

ОБНОВЛЕНО: Есть более простой способ! Во-первых, назначьте свою легенду переменной при ее создании:

leg = plt.legend()

Тогда:

for lh in leg.legendHandles: 
    lh._legmarker.set_alpha(0)

ИЛИ

for lh in leg.legendHandles: 
    lh.set_alpha(0)

чтобы сделать ваши маркеры прозрачными для plt.plot или plt.scatter, соответственно.

Обратите внимание, что использование простого lh.set_alpha(0) в plt.plot сделает строки в вашей легенде прозрачными, а не маркерами. Вы должны уметь адаптировать эти две возможности для других типов сюжетов.

Источники: Синтезирован из хорошего совета DrV о размерах маркеров. Обновление было вдохновлено полезным комментарием Owen.

Ответ 4

Я обнаружил, что функция .set_alpha() работает во многих объектах легенды, но, к сожалению, многие объекты легенды имеют несколько частей (например, вывод errorbar()), а вызов .set_alpha() влияет только на один из них.

Можно использовать .get_legend_handles_labels(), а затем прокручивать части дескрипторов и .set_alpha(), но, к сожалению, copy.deepcopy(), похоже, не работает в списке дескрипторов, поэтому сам график будет затронут. Лучшим обходным решением, которое я мог найти, было сохранение оригинальных альфах, .set_alpha() в соответствии с тем, что я хотел, создать легенду, затем reset сюжет альфа возвращается к исходным значениям. Было бы намного чище, если бы я мог сделать глубокую handles (мне не нужно было бы сохранять альфа-значения или reset их), но я не мог сделать этого в python2.7 (возможно, это зависит от того, какие объекты находятся в легенде).

f,ax=plt.subplots(1)

ax.plot(  ...  )

def legend_alpha(ax,newalpha=1.0):
    #sets alpha of legends to some value
    #this would be easier if deepcopy worked on handles, but it doesn't 
    handles,labels=ax.get_legend_handles_labels()
    alphass=[None]*len(handles) #make a list to hold lists of saved alpha values
    for k,handle in enumerate(handles): #loop through the legend entries
        alphas=[None]*len(handle) #make a list to hold the alphas of the pieces of this legend entry
        for i,h in enumerate(handle): #loop through the pieces of this legend entry (there could be a line and a marker, for example)
            try: #if handle was a simple list of parts, then this will work
                alphas[i]=h.get_alpha()
                h.set_alpha(newalpha)
            except: #if handle was a list of parts which themselves were made up of smaller subcomponents, then we must go one level deeper still.
                #this was needed for the output of errorbar() and may not be needed for simpler plot objects
                alph=[None]*len(h) 
                for j,hh in enumerate(h):
                    alph[j]=hh.get_alpha() #read the alpha values of the sub-components of the piece of this legend entry
                    hh.set_alpha(newalpha)
                alphas[i]=alph #save the list of alpha values for the subcomponents of this piece of this legend entry
        alphass[k]=alphas #save the list of alpha values for the pieces of this legend entry
    leg=ax.legend(handles,labels) #create the legend while handles has updated alpha values
    for k,handle in enumerate(handles): #loop through legend items to restore origina alphas on the plot
        for i,h in enumerate(handle): #loop through pieces of this legend item to restore alpha values on the plot
            try: 
                h.set_alpha(alphass[k][i])
            except:
                for j,hh in enumerate(h): #loop through sub-components of this piece of this legend item to restore alpha values
                    hh.set_alpha(alphass[k][i][j])
    return leg

leg=legend_alpha(ax)
leg.draggable()