2012-04-26 26 views
5

Nuevo usuario de matplotlib aquí. Intento trazar una línea de datos codificada por colores, o mejor, un rango de datos codificados por colores. Intervalos de codificación de color a lo largo del eje y. Sigue una secuencia de comandos de demostración cruda:Matplotlib: cuadrículas y gráficos de colores y valores/rangos de datos

import matplotlib.pyplot as plt 

# dummy test data 
datapoints = 25 
maxtemps = [ 25, 24, 24, 25, 26, 27, 22, 21, 22, 19, 17, 14, 13, 12, 11, 12, 11, 10, 9, 9, 9, 8, 9, 9, 8 ] 
mintemps = [ 21, 22, 22, 22, 23, 24, 18, 17, 16, 14, 10, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 4, 3, 4, 3 ] 
times = list(xrange(datapoints)) 

# cap a filled plot at a given level 
def capped(indata, cap): 
    outdata = [0] * datapoints 
    lcount = 0 

    while lcount < datapoints: 
     if indata[lcount] > cap: 
      outdata[lcount] = cap 
     else: 
      outdata[lcount] = indata[lcount] 
     lcount += 1 
    return outdata 

fig = plt.figure() 

ax1 = fig.add_subplot(111) 
ax1.fill_between(times, 0, maxtemps, color='#FF69B4', zorder=1, linewidth=0.1) 
ax1.fill_between(times, 0, capped(maxtemps,25), color='#F08228', zorder=2, linewidth=0.1) 
ax1.fill_between(times, 0, capped(maxtemps,20), color='#E6AF2D', zorder=3, linewidth=0.1) 
ax1.fill_between(times, 0, capped(maxtemps,15), color='#E6DC32', zorder=4, linewidth=0.1) 
ax1.fill_between(times, 0, capped(maxtemps,10), color='#A0E632', zorder=5, linewidth=0.1) 
ax1.fill_between(times, 0, capped(maxtemps,5), color='#00DC00', zorder=6, linewidth=0.1) 
ax1.fill_between(times, 0, mintemps, color='#FFFFFF', zorder=7, linewidth=0.1) 
plt.setp(ax1.get_xticklabels(), visible=False) 
ax1.grid(True, zorder=8) 
ylim(0) 
plt.draw() 
plt.show() 

Hace la mayor parte del trabajo, pero plantea dos preguntas.

  1. ¿Hay una forma más directa y elegante de lograr este mismo efecto con una característica matplotlib que desconozco? ¿Eso es trazar una matriz 1D de (por ejemplo) datos de series de tiempo, o ilustrar un rango entre dos conjuntos de tales datos (por ejemplo, temperaturas máximas y mínimas)?

  2. Por más que lo intente, no puedo convencer a las líneas de la cuadrícula para que tracen en la parte superior de la figura. Siempre parecen sentarse en la parte superior del primer conjunto de datos trazados y luego quedan ocultos por los datos trazados posteriores, dejando en blanco la mitad inferior de la trama. El uso de zorder parece ser ignorado.

Muchas gracias.

Respuesta

9

para responder a su segunda pregunta:

puede configurar todo el fill_between zorder a 0,1, 0,2, 0,3 ...

líneas de la cuadrícula pertenecen al eje X y el eje Y y el eje x y zorder del eje Y es 2.5. Entonces cualquier zorder menor a 2.5 se mostrará debajo de las líneas de la grilla.

que escribir un código similar con la suya, pero el uso de bucle y numpy.interp, numpy.clip hacer la trama del clip:

import pylab as pl 
import numpy as np 
maxtemps = [ 25, 24, 24, 25, 26, 27, 22, 21, 22, 19, 17, 14, 13, 12, 11, 12, 11, 10, 9, 9, 9, 8, 9, 9, 8 ] 
mintemps = [ 21, 22, 22, 22, 23, 24, 18, 17, 16, 14, 10, 8, 8, 7, 7, 6, 5, 5, 5, 4, 4, 4, 3, 4, 3 ] 
times = list(xrange(len(mintemps))) 

colors = [ 
    (25, '#FF69B4'), 
    (20, '#F08228'), 
    (15, '#E6AF2D'), 
    (10, '#E6DC32'), 
    (5, '#A0E632'), 
    (0, '#00DC00') 
] 

# change 300 to larger number if you need more accuracy. 
x = np.linspace(times[0], times[-1], 300) 
maxt = np.interp(x, times, maxtemps) 
mint = np.interp(x, times, mintemps) 

last_level = np.inf 
for level, color in colors:  
    tmp_min = np.clip(mint, level, last_level) 
    tmp_max = np.clip(maxt, level, last_level) 
    pl.fill_between(x, tmp_min, tmp_max, lw=0, color=color) 
    last_level = level 

pl.grid(True) 
pl.show() 

enter image description here

Cuestiones relacionadas