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