2017-01-09 2 views
2

Ich versuche, ein Streudiagramm aus ~ 6 Millionen Punkten zu machen, um eine Art von Clustering zu verstehen.matplotlib scatter plotting über png

Wenn ich versuche, dies in einem einfachen Scatter-Befehl zu tun, beschwert sich Matplotlib über übermäßigen Speicher. Also habe ich beschlossen, 3000 Punkte zu plotten und dann die Figur im .png-Format zu speichern, die Figur zu löschen, die gespeicherte .png mit imread() zu laden und dann die nächsten 3000 Punkte zu überlagern.

Ich bin mit einigen Problemen konfrontiert und ich verstehe nicht, wie sie entstanden sind. Mein Code ist ein bisschen zu lang, da ich eine Menge von Textdateien Parsen aber unten ist ein Beispiel Mockup-Code, der mein Denken repliziert:

import matplotlib.pyplot as plt 
fig, ax = plt.subplots() 
plt.xlim(0,1000) 
plt.ylim(-1000,1000) 
plt.scatter(400,500,marker="+",c="r") 
plt.gca().set_aspect('equal') 
plt.draw() 
plt.savefig(r"C:\TMP\fig1.png") 
plt.clf() 
im = plt.imread(r"C:\TMP\fig1.png") 
implot = plt.imshow(im, origin='upper', aspect='equal', extent=[0,1000,-1000,1000], zorder=0) 
plt.scatter(600,500,marker="+",c="b") 
plt.savefig(r"C:\TMP\fig2.png") 
plt.close(fig) 

Das Ergebnis ist etwas, das ich nicht verstehen, wie zu interpretieren. Offensichtlich, ich nicht verstehe die Beziehung zwischen "Aspekt" und "Umfang" von IMshow(). Kann mir jemand dabei helfen?

Abbildung 1

fig1.png

Abbildung 2

fig2.png

Ich war beide fig1.png und fig2.png erwartet ein weiteres perfekt Overlay auf der Oberseite.

Antwort

1

Ich machte ein Speicherprofil mit memory_profiler für ein sinnvolles Beispiel für 6M Punkte.

import numpy as np 
import time 
x = np.random.normal(size=6000000) 
y = np.random.normal(size=6000000) 

start = time.time() 
plt.scatter(x, y, alpha=0.1) 
end = time.time() - start 
print(end) 

out ist 30,015294551849365 Sekunden. Es ist nicht besonders langsam.

Auf der anderen Seite ist das Profil Ausgabe:

Line # Mem usage Increment Line Contents 
================================================ 
5 81.738 MiB 0.000 MiB @profile 
6        def make_test(): 
7 127.516 MiB 45.777 MiB  x = np.random.normal(size=6000000) 
8 173.293 MiB 45.777 MiB  y = np.random.normal(size=6000000) 
9        
10 282.934 MiB 109.641 MiB  plt.scatter(x, y, alpha=0.1) 
11 298.160 MiB 15.227 MiB  plt.savefig('big_plot') 

Er erreicht bis zu 300 Mb auf, die entweder kein Speicherproblem ist. Das Problem ist woanders, aber Sie sollten ALL die Punkte zusammen plotten können.

Schließlich ist die Streudiagramm:

big_scatter_plot

+0

Dank! Ich werde wieder über mein Skript schauen. Ich habe vielleicht etwas verpasst, aber die Auffüllung beim Laden der fig1.png mit imshow() macht mich verrückt. Wie kann ich herausfinden, warum das PNG nicht perfekt mit der zweiten Figur überlagert ist? Es war nicht meine Absicht, eine Handlung in einem Grundstück zu bekommen ... – kabel

+0

Ich finde nicht heraus, was das Problem ist, aber es ist ** NICHT ** eine gute Idee. Ich schlage vor, Sie machen es anders. – Lucas

+0

Kein Problem, danke für Ihre Eingabe. Was ich zu erklären versuchte, ist, dass ich in der zweiten Figur nicht zwei Achssätze sehen möchte, wenn ich Plot-Save-Load-Plot wie ursprünglich geplant (mit jeweils nur 3000 Punkten) zeichnen möchte. Die gespeicherte Figur (Abbildung 1 oben) wird nicht richtig skaliert und ich komme mit Abbildung 2, die zwei Sätze von Achsen hat (eine aus der PNG und eine aus der neu erstellten Figur). Es gibt ein Padding-Problem, das ich nicht verstehe, wie es mit imshow() funktioniert. Oder ich könnte mein Skript ändern, wie Sie es vorschlagen. Vielen Dank. – kabel

Verwandte Themen