2011-10-15 16 views
20

Este es un tipo de pregunta de seguimiento al post this, donde se discutió la coloración de los ejes, marcas y etiquetas. Espero que esté bien abrir una nueva pregunta extendida para esto.Cambiando elegantemente el color de un cuadro de trama en matplotlib

Cambiando el color de un cuadro completo (marcas y ejes) alrededor de una doble trama (a través de add_subplot) con ejes [ax1, ax2] resulta en una gran cantidad de código. Este fragmento de código cambia el color del marco de la trama superior: (!)

ax1.spines['bottom'].set_color('green') 
ax1.spines['top'].set_color('green') 
ax1.spines['left'].set_color('green') 
ax1.spines['right'].set_color('green') 
for t in ax1.xaxis.get_ticklines(): t.set_color('green') 
for t in ax1.yaxis.get_ticklines(): t.set_color('green') 
for t in ax2.xaxis.get_ticklines(): t.set_color('green') 
for t in ax2.yaxis.get_ticklines(): t.set_color('green') 

Así que para cambiar el color del marco de dos parcelas con dos ejes Y cada uno, necesitaría 16 líneas de código .. . Esta es la forma en que parece:

enter image description here

Otros métodos desenterré hasta ahora:

  • matplotlib.rc: discutido here; cambia globalmente, no localmente. Quiero tener otras parcelas en diferentes colores. Por favor, no hay discusiones acerca de demasiados colores en parcelas ... :-)

    matplotlib.rc('axes',edgecolor='green') 
    
  • desenterrar las espinas del eje, y luego cambiarlo: también discutido here; no es realmente elegante, creo.

    for child in ax.get_children(): 
        if isinstance(child, matplotlib.spines.Spine): 
         child.set_color('#dddddd') 
    

¿Existe un elegante manera de condensar el bloque anterior, algo más "Pythonic"?

Estoy usando python 2.6.5 con matplotlib 0.99.1.1 bajo ubuntu.

Respuesta

12

Refactorizando código anterior:

import matplotlib.pyplot as plt 

for ax, color in zip([ax1, ax2, ax3, ax4], ['green', 'green', 'blue', 'blue']): 
    plt.setp(ax.spines.values(), color=color) 
    plt.setp([ax.get_xticklines(), ax.get_yticklines()], color=color) 
+0

Bueno. Por favor incluye los dos colores y voy a 'aceptar' tu respuesta. (como: 'para hacha, color en zip ([ax1, ax2, ax3, ax4], ['verde', 'verde', 'azul', 'azul']): plt.setp (ax.spines.values(), color = color); plt.setp ([ax.get_xticklines(), ax.get_yticklines()], color = color) ') – Boffin

+0

@Boffin hecho :) – ianalis

+0

en su última línea Creo que usted quiso decir' ax1 'ser simplemente' ax' – Joel

9

Suponiendo que está utilizando una versión razonablemente actualizada de matplotlib (> = 1.0), tal vez intentar algo como esto:

import matplotlib.pyplot as plt 

# Make the plot... 
fig, axes = plt.subplots(nrows=2) 
axes[0].plot(range(10), 'r-') 
axes[1].plot(range(10), 'bo-') 

# Set the borders to a given color... 
for ax in axes: 
    ax.tick_params(color='green', labelcolor='green') 
    for spine in ax.spines.values(): 
     spine.set_edgecolor('green') 

plt.show() 

enter image description here

+0

corro matplotlib 0.99.1.1 (D'oh!). Además, no expliqué muy bien la trama doble. Actualicé la pregunta inicial y agregué un gráfico.Mostraste otra posibilidad de colorear ejes que puedo agregar a mi lista (si ejecutas una versión actualizada de m.p.l.). ¿El tuyo es aún más corto si coloreas un cuadro con dos ejes y en un gráfico? – Boffin

3

Tal vez es un poco crudo a responde mi propia pregunta, pero me gustaría compartir lo que pude encontrar hasta ahora. Esta versión puede colorear dos subparcelas con los ejes [ax1, ax2] y [ax3, ax4] en dos colores diferentes. Es mucho más corto que las 16 líneas que indiqué en mi pregunta anterior. Está inspirado por la respuesta de Joe Kington aquí y en twinx kills tick label color.

import matplotlib.pyplot as plt 
import numpy as np 

# Generate some data 
num = 200 
x = np.linspace(501, 1200, num) 
yellow_data, green_data , blue_data= np.random.random((3,num)) 
green_data += np.linspace(0, 3, yellow_data.size)/2 
blue_data += np.linspace(0, 3, yellow_data.size)/2 

fig = plt.figure() 
plt.subplot(211) # Upper Plot 
ax1 = fig.add_subplot(211) 
ax1.fill_between(x, 0, yellow_data, color='yellow') 
ax2 = ax1.twinx() 
ax2.plot(x, green_data, 'green') 
plt.setp(plt.gca(), xticklabels=[]) 
plt.subplot(212) # Lower Plot 
ax3 = fig.add_subplot(212) 
ax3.fill_between(x, 0, yellow_data, color='yellow') 
ax4 = ax3.twinx() 
ax4.plot(x, blue_data, 'blue') 

# Start coloring 
for ax, color in zip([ax1, ax2, ax3, ax4], ['green', 'green', 'blue', 'blue']): 
    for ticks in ax.xaxis.get_ticklines() + ax.yaxis.get_ticklines(): 
     ticks.set_color(color) 
    for pos in ['top', 'bottom', 'right', 'left']: 
     ax.spines[pos].set_edgecolor(color) 
# End coloring 

plt.show() 

color_plots

he marcado esto como aceptado, ya que es la solución más compacta que he podido encontrar hasta ahora. Aún así, estoy abierto a otras formas, quizás más elegantes, de resolverlo.

Cuestiones relacionadas