2017-02-08 7 views
3

I haben eine Liste von numpy-Arrays, die jeweils potentiell eine unterschiedliche Anzahl von Elementen, wie zum Beispiel:Plotten Listen mit unterschiedlicher Anzahl von Elementen in matplotlib

[array([55]), 
array([54]), 
array([], dtype=float64), 
array([48, 55]),] 

Ich möchte dies plotten, wobei jedes Array hat eine Abszisse (x-Wert) zugewiesen, wie [1,2,3,4], so dass das Diagramm die folgenden Punkte zeigen sollte: [[1,55], [2, 54], [4, 48], [4, 55]]. Kann ich das mit Matplotlib machen? oder wie kann ich die Daten zuerst mit numpy oder pandas transformieren, so dass es geplottet werden kann?

Antwort

4

Was Sie tun möchten, ist das ursprüngliche Array ketten und ein neues Array mit "Abszissen" generieren. Es gibt viele Wege zu verketten, eine der effizientesten ist die Verwendung itertools.chain.

import itertools 
from numpy import array 

x = [array([55]), array([54]), array([]), array([48, 55])] 

ys = list(itertools.chain(*x)) 
# this will be [55, 54, 48, 55] 

# generate abscissas 
xs = list(itertools.chain(*[[i+1]*len(x1) for i, x1 in enumerate(x)])) 

Jetzt können Sie nur mit matplotlib leicht plotten, wie unten

import matplotlib.pyplot as plt 
plt.plot(xs, ys) 
+0

Nicht wirklich. Ich brauche die letzten zwei Elemente, 48 und 55, die in demselben Fall mit der gleichen Abzisse verbunden sind (das gleiche x). –

+0

Wenn Sie eine einzelne Zeile plotten möchten, habe ich den obigen Code geändert. Nicht ganz sicher, was Sie versuchen zu plotten, aber das obige wird tun –

+2

Das funktioniert, aber um 'xs = [1, 2, 4, 4]' wie angefordert zu bekommen, müssen Sie '[[i + 1] * len (x1) für i, x1 in enumerate (x)] '. (Derzeit gibt es '[0, 1, 3, 3]') – tom

0

mit x Ihrer Liste:

[plt.plot(np.repeat(i,len(x[i])), x[i],'.') for i in range(len(x))] 
plt.show() 
+0

Seine schlechte Praxis, eine Liste 'liste' zu ​​nennen – tom

+0

Sie haben Recht, es war nur für das Beispiel :) –

+0

Danke, aber meine aktuelle Liste ist sehr groß, und ich denke nicht, dass es so effizient sein wird, "Plot" so oft zu nennen. –

0

@Alessandro Mariani Antwort basierend auf itertools mich an eine andere Art und Weise denken gemacht erzeuge ein Array mit den benötigten Daten. In einigen Fällen kann es kompakter sein. Es basiert auch auf itertools.chain:

import itertools 
from numpy import array 

y = [array([55]), array([54]), array([]), array([48, 55])] 
x = array([1,2,3,4]) 
d = array(list(itertools.chain(*[itertools.product([t], n) for t, n in zip(x,y)]))) 

d sich jetzt das folgende Array:

array([[ 1, 55], 
     [ 2, 54], 
     [ 4, 48], 
     [ 4, 55]]) 
1

Wenn Sie verschiedenen Marker für verschiedene Gruppen von Daten (die Farben automatisch durch matplotlib gefahren werden) haben wollen:

import numpy as np 
import matplotlib.pyplot as plt 

markers = ['o', #'circle', 
      'v', #'triangle_down', 
      '^', #'triangle_up', 
      '<', #'triangle_left', 
      '>', #'triangle_right', 
      '1', #'tri_down', 
      '2', #'tri_up', 
      '3', #'tri_left', 
      '4', #'tri_right', 
      '8', #'octagon', 
      's', #'square', 
      'p', #'pentagon', 
      'h', #'hexagon1', 
      'H', #'hexagon2', 
      'D', #'diamond', 
      'd', #'thin_diamond' 
      ] 

n_markers = len(markers) 

a = [10.*np.random.random(int(np.random.random()*10)) for i in xrange(n_markers)] 

fig = plt.figure() 
ax = fig.add_subplot(111) 
for i, data in enumerate(a): 
    xs = data.shape[0]*[i,] # makes the abscissas list 
    marker = markers[i % n_markers] # picks a valid marker 
    ax.plot(xs, data, marker, label='data %d, %s'%(i, marker)) 

ax.set_xlim(-1, 1.4*len(a)) 
ax.set_ylim(0, 10) 
ax.legend(loc=None) 
fig.tight_layout() 

Graph with different markers Beachten Sie die Grenzen y Skala sind hart codiert, ändern Sie entsprechend. Die 1.4*len(a) soll Platz auf der rechten Seite des Graphen für die Legende lassen.

Das Beispiel hat über keinen Punkt in der x=0 (würde dunkelblaue Kreise sein), wie die zufällig zugewiesen Größe für seine Datensatz Null war, aber man kann leicht ein +1 platzieren, wenn Sie nicht x=0 verwenden möchten.

1

Pandas Mit einem numpy Array mit nans eingefügt zu erstellen, wenn ein Array als die längste Array in der Liste leer oder kürzer ist ...

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

arr_list = [np.array([55]), 
      np.array([54]), 
      np.array([], dtype='float64'), 
      np.array([48, 55]),] 

df = pd.DataFrame(arr_list) 
list_len = len(df) 
repeats = len(list(df)) 
vals = df.values.flatten() 
xax = np.repeat(np.arange(list_len) + 1, repeats) 
df_plot = pd.DataFrame({'xax': xax, 'vals': vals}) 
plt.scatter(df_plot.xax, df_plot.vals); 
Verwandte Themen