Установить непрозрачность символа легенды с помощью 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 )

Ответы на вопрос(6)

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

plt.plot(x, y, 'ro', label='label')
for lh in plt.gca().get_legend_handles_labels():
    lh[0].set_alpha(new_alpha)

Я хотел бы объяснить, почему это работает, но я не могу. Также я не уверен, что это работает для всех бэкэндов.

И да, я знаю, что вопрос старый. Поскольку это все еще появляется в Google, я найду это позже и помогу моему будущему сам.

 Don Kirkby06 нояб. 2018 г., 00:19
Это не работает для меня в Matplotlib 2.0.0.
 StSav01207 нояб. 2018 г., 12:27
Почему бы вам не обновитьmatplotlib тогда?
 Don Kirkby07 нояб. 2018 г., 18:56
Я обновился до 2.2.3, и он все еще не работал для меня. Однако ваша идея изменить альфу после создания легенды сработала, поэтому я разместил отдельнуюответ с полным примером.

чтобы сделать «поддельные» строки для легенды невидимыми на графике, вы можете использовать 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()

есть более простой способ! Сначала назначьте вашу легенду переменной при ее создании:

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 о размерах маркера. Обновление было вдохновлено полезным комментарием отОуэн.

 John Haberstroh05 июл. 2017 г., 01:58
Это должен быть абсолютно принятый ответ.
 CaptainKinematics24 мая 2017 г., 10:39
Кроме того, мой исходный ответ и ваш комментарий используют альфа = 1. чтобы получить прозрачность, но когда я играю с ней сейчас, мне нужно альфа = 0. (matplotlib .__ version__ == '1.5.1'). Я принимаю сумасшедшие таблетки или что-то?
 Owen23 мая 2017 г., 15:49
Это был самый простой ответ на мою проблему! Я бы добавил две заметки: 1) Вы можете получить опцию легенды,leg = plt.legend() когда вы создаете легенду. 2) Мне нужно былоlh.set_alpha(1) неlh._legmarker.set_alpha(1) (не уверен, что API изменился ...)
 CaptainKinematics24 мая 2017 г., 10:37
Хорошая заметка. Вы использовалиplt.scatter()? Немного поиграв с ним, похоже, что есть несколько небольших вариантов в зависимости от типа вашего сюжета (возможно, потому чтоplt.scatter не имеет конкретного_legmarker поскольку ему никогда не нужно различать линии и маркеры.)
Решение Вопроса

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

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)

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

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

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

после он копирует альфа-уровень в легенду. Это означает, что вы можете создать линии графика с тем уровнем альфа, который вы хотите в легенде, создать легенду, чтобы скопировать этот уровень альфа, а затем изменить уровень альфа на линиях графика.

Вот полный пример:

import matplotlib.pyplot as plt

x = (0, 1, 2)
y = (0, 2, 1)
line, = plt.plot(x, y, 'ro', label='label')  # Default alpha is 1.0.
plt.legend()  # Copy alpha to legend.
line.set_alpha(0.2)  # Change alpha for data points.

plt.show()

Этот график выглядит так, когда я запускаю его с помощью matplotlib 2.2.3 на Python 2.7.15:

Ваш ответ на вопрос