2012-10-11 195 views
16

Estoy trabajando en un diagrama con marcadores translúcidos 'x' (20% alfa). ¿Cómo hago que el marcador aparezca con 100% de opacidad en la leyenda?Establecer la opacidad del símbolo de la leyenda con matplotlib?

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) 

Respuesta

3

Si usted quiere tener algo específico en su leyenda, que es más fácil de definir los objetos que se colocan en la leyenda con el texto apropiado. Por ejemplo:

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) 

Aquí, línea 1 define una línea corta, blanco (tan esencialmente invisible) con el marcador de 'x' en la opacidad rojo y completa. Como ejemplo, line2 te da una línea azul más larga sin marcadores visibles. Al crear estas "líneas", puede controlar más fácilmente sus propiedades dentro de la leyenda.

6

El seguimiento de la respuesta de Cosmosis, para que las líneas "falsos" de la leyenda invisible en la trama, puede utilizar NaNs, y que todavía va a trabajar para generar entradas de leyenda:

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() 
0

tengo encontró que la función .set_alpha() funciona en muchos objetos de leyenda, pero desafortunadamente, muchos objetos de leyenda tienen varias piezas (como la salida de errorbar()) y la llamada .set_alpha() solo afectará a una de ellas.

Uno puede usar .get_legend_handles_labels() y luego bucle a través de partes de las asas y .set_alpha(), pero, por desgracia, copy.deepcopy() no parecen funcionar en la lista de identificadores, por lo que la trama en sí se verá afectada. La mejor solución que pude encontrar fue guardar los alfas originales, .set_alpha() en lo que yo quería, crear la leyenda y luego restablecer las alfas de la trama a sus valores originales. Sería mucho más claro si pudiera hacer una copia profunda del documento (no tendría que guardar valores alfa ni restaurarlos), pero no podría hacerlo en python2.7 (quizás esto dependa de qué objetos estén en la leyenda).

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() 
8

ACTUALIZADO: ¡Hay una manera más fácil! En primer lugar, asignar su leyenda a una variable al crearla:

leg = plt.legend() 

continuación:

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

O

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

para hacer sus marcadores transparente para un plt.plot o una plt.scatter, respectivamente .

Tenga en cuenta que usar simplemente lh.set_alpha(0) en un plt.plot hará que las líneas de su leyenda sean transparentes en lugar de los marcadores. Debería poder adaptar estas dos posibilidades para los otros tipos de gráficos.

Fuentes: Sintetizado a partir de algunos good advice por DrV sobre los tamaños de los marcadores. La actualización se inspiró en comentarios útiles de Owen.

+1

¡Esta fue de lejos la respuesta más simple para mi problema! Agregaría dos notas: 1) Puede obtener la opción de leyenda por 'leg = plt.legend()' cuando crea la leyenda. 2) Para mí necesitaba 'lh.set_alpha (1)' not 'lh._legmarker.set_alpha (1)' (no estoy seguro de si la API ha cambiado ...) – Owen

+0

Buena nota. ¿Estabas usando 'plt.scatter()'?Después de jugar con él un poco, parece que hay algunas variantes ligeras dependiendo de su tipo de gráfica (probablemente porque 'plt.scatter' no tiene un' _legmarker' específico ya que nunca necesita distinguir entre líneas y marcadores). – CaptainKinematics

+0

Además, mi respuesta original y tu comentario ambos usan alfa = 1. para obtener transparencia, pero cuando juego con ella ahora encuentro que necesito alfa = 0. (matplotlib .__ version__ == '1.5.1'). ¿Estoy tomando pastillas locos o algo así? – CaptainKinematics

Cuestiones relacionadas