2012-01-20 13 views
6

Ho una matrice di valori y che formano una linea. Inoltre, ho una matrice con lo stesso numero di elementi della matrice y di valori che vanno da 0 a 1. Chiameremo questo array 'z'. Voglio tracciare l'array di valori y in modo che il colore di ogni punto corrisponda al valore z.gnuplot variabile linecolor in matplotlib?

In gnuplot, si può fare questo con il 'variabile lc':

plot ’data’ using 1:2:3 with points lc variable 

Utilizzando il consiglio da qui: Matplotlib scatterplot; colour as a function of a third variable , sono stato in grado di utilizzare un grafico a dispersione, che ha fatto il lavoro:

import matplotlib as mpl 
import matplotlib.pyplot as plt 

plt.scatter(x, y, c=z, s=1, edgecolors='none', cmap=mpl.cm.jet) 
plt.colorbar() 
plt.show() 

c'è un modo per fare questo con il metodo trama in matplotlib, simile a questo?

plt.plot(x, y, c=z) 

Quando ho provato il codice precedente, tutte le linee sono apparse solo in nero.

+0

In gnuplot 'lc variable' seleziona il tipo di linea * indice * basati sulla valore dell'ultima colonna. Per usarlo come colore, usa per es. 'lc palette z'. – Christoph

risposta

2

è possibile utilizzare dispersione:

plt.scatter(range(len(y)), y, c=z, cmap=cm.hot) 

qui si ha la ipython sessione -pylab:

In [27]: z = [0.3,0.4,0.5,0.6,0.7,0.2,0.3,0.4,0.5,0.8,0.9] 

In [28]: y = [3, 7, 5, 6, 4, 8, 3, 4, 5, 2, 9] 

In [29]: plt.scatter(range(len(y)), y, s=60, c=z, cmap=cm.hot) 
Out[29]: <matplotlib.collections.PathCollection at 0x9ec8400> 

enter image description here

Se si desidera utilizzare trama si può ottenere la cifra equivalente sopra con (sessione di pycrust):

>>> from matplotlib import pyplot as plt 
>>> from matplotlib import cm 
>>> y = [3,7,5,6,4,8,3,4,5,2,9] 
>>> z = [0.3,0.4,0.5,0.6,0.7,0.2,0.3,0.4,0.5,0.8,0.9] 
>>> for x, (v, c) in enumerate(zip(y,z)): 
...  plt.plot(x,v,marker='o', color=cm.hot(c)) 
...  
[<matplotlib.lines.Line2D object at 0x0000000008C42518>] 
[<matplotlib.lines.Line2D object at 0x0000000008C426D8>] 
[<matplotlib.lines.Line2D object at 0x0000000008C42B38>] 
[<matplotlib.lines.Line2D object at 0x0000000008C452B0>] 
[<matplotlib.lines.Line2D object at 0x0000000008C45438>] 
[<matplotlib.lines.Line2D object at 0x0000000008C45898>] 
[<matplotlib.lines.Line2D object at 0x0000000008C45CF8>] 
[<matplotlib.lines.Line2D object at 0x0000000008C48198>] 
[<matplotlib.lines.Line2D object at 0x0000000008C485F8>] 
[<matplotlib.lines.Line2D object at 0x0000000008C48A58>] 
[<matplotlib.lines.Line2D object at 0x0000000008C4B1D0>] 
>>> plt.show() 
>>> 
+0

Grazie joaquin. Ho deciso di usare la dispersione invece della trama. –

17

Ho avuto lo stesso problema: volevo tracciare linee con un colore non uniforme, che volevo dipendere da una terza variabile (z).

Ma ho sicuramente voluto usare una linea, non i marcatori (come nella risposta di @ joaquin). Ho trovato una soluzione in un matplotlib gallery example, utilizzando la classe matplotlib.collections.LineCollection (collegamento here).

Ecco il mio esempio, che riporta traiettorie in una mappa di base, loro colorazione secondo l'altezza:

import matplotlib.pyplot as plt 
from mpl_toolkits.basemap import Basemap 
from matplotlib.collections import LineCollection 
import numpy as np 

m = Basemap(llcrnrlon=-42,llcrnrlat=0,urcrnrlon=5,urcrnrlat=50, resolution='h') 
fig = plt.figure() 
m.drawcoastlines() 
m.drawcountries() 

for i in trajectorias: 
    # for each i, the x (longitude), y (latitude) and z (height) 
    # are read from a file and stored as numpy arrays 

    points = np.array([x, y]).T.reshape(-1, 1, 2) 
    segments = np.concatenate([points[:-1], points[1:]], axis=1) 

    lc = LineCollection(segments, cmap=plt.get_cmap('Spectral'), 
         norm=plt.Normalize(250, 1500)) 
    lc.set_array(z) 
    lc.set_linewidth(2) 

    plt.gca().add_collection(lc) 

axcb = fig.colorbar(lc) 
axcb.set_label('cota (m)') 

plt.show() 

height dependent trajectories

+0

Molto bello esempio! – Christoph

+0

Se si desidera una transizione più fluida tra i segmenti di linea, è possibile eseguire 'segments = np.concatenate ([points [: - 2], points [1: -1], points [2:]], axis = 1)'. – shockburner