Ich habe den folgenden Code, um einen Streamplot basierend auf einer interp1d
-Zwischeninterpolation von diskreten Daten zu erzeugen:
Ich habe die csv-Datei hier hochgeladen, wenn du ein paar Sachen Ссылка ausprobieren willst . Was die folgende Handlung erzeugt:
Ich bin eigentlich ziemlich glücklich mit dem Ergebnis, bis auf ein kleines Detail, das ich nicht herausfinden kann: Wenn man genau hinsieht, ändert sich die Linienbreite und die Farbe in ziemlich großen Schritten, was besonders in der Mitte sichtbar ist:
Gibt es eine Möglichkeit, mit der ich die Größe dieser Schritte verringern kann, um die Colormap besonders zu ersticken?
Ich habe mir das nochmal angesehen und es war nicht so schmerzhaft wie ich dachte.
Hinzufügen:
%Vor% nachdem ty
in der Trajektorien-Schleife initialisiert wurde (Zeile 164
in meiner Version). Ersetzen Sie einfach die Anzahl der gewünschten Unterteilungen für subdiv = 15
. Alle Segmente im Streamplot werden in so viele gleich große Segmente unterteilt, wie Sie möchten. Die Farben und Linienbreiten für beide werden immer noch richtig aus der Interpolation der Daten erhalten.
Es ist nicht so sauber wie die Änderung des Integrationsschrittes, aber es zeichnet genau die gleichen Trajektorien.
Wenn es Ihnen nichts ausmacht, den streamplot
-Code ( matplotlib/streamplot.py
) zu ändern, können Sie einfach die Größe der Integrationsschritte verringern. Innerhalb _integrate_rk12()
ist die maximale Schrittweite definiert als:
Wenn Sie das verringern, sagen wir:
%Vor%Ich bekomme dieses Ergebnis (links = neu, rechts = original):
Natürlich macht dies den Code ungefähr 10x langsamer, und ich habe ihn nicht gründlich getestet, aber er scheint für dieses Beispiel (als schneller Hack) zu funktionieren.
Über die Dichte (in den Kommentaren erwähnt): Ich persönlich sehe das Problem nicht. Es ist nicht so, dass wir versuchen, die tatsächliche Pfadlinie (z. B. eines Teilchens) zu visualisieren; Die Dichte ist bereits eine willkürliche (kontrollierbare) Wahl, und ja, sie wird durch Wahlmöglichkeiten in der Integration beeinflusst, aber ich denke nicht, dass sie die (nicht ganz sicher, wie wir das nennen) erforderliche Visualisierung, die wir anstreben, verändern.
Die Ergebnisse (Dichte) scheinen bei abnehmenden Schrittgrößen etwas konvergent zu sein, dies zeigt die Ergebnisse für die Verringerung des Integrationsschrittes mit einem Faktor {1,5,10,20}:
Sie können den Parameter density
erhöhen, um weichere Farbübergänge zu erzielen.
Verwenden Sie dann jedoch den Parameter start_points
, um das allgemeine Durcheinander zu reduzieren.
Mit dem Parameter start_points können Sie explizit den Standort und auswählen
Anzahl der Trajektorien zum Zeichnen. Es überschreibt den Standard, der plotten soll
so viele wie möglich, um die gesamte Handlung zu füllen.
Aber zuerst brauchen Sie einen kleinen Fix zu Ihrem bestehenden Code: Laut der streamplot -Dokumentation sollten die X- und Y-Argumente 1D-Arrays sein, nicht 2D-Arrays produziert von mgrid. Es sieht so aus, als ob die Übergabe in 2D-Arrays unterstützt wird, aber es ist nicht dokumentiert und es ist derzeit nicht kompatibel mit dem start_points-Parameter.
Hier habe ich Ihre X, Y, Vx, Vy und Geschwindigkeit überarbeitet:
%Vor% Jetzt können Sie den Parameter start_points
explizit festlegen. Die Startpunkte sind tatsächlich
"Samen" Punkte. Jede gegebene Stream-Trajektorie wird in beiden Richtungen wachsen
vom Keimpunkt. Also, wenn Sie einen Saatpunkt genau in der Mitte von
Im Beispielplot wird es sowohl nach oben als auch nach unten wachsen, um eine Vertikale zu erzeugen
Stromleitung.
Neben der Kontrolle der Nummer von Trajektorien, verwenden Sie die
start_points
-Parameter steuert auch die Reihenfolge , die sie sind
gezeichnet. Dies ist wichtig, wenn man bedenkt, wie Trajektorien enden.
Sie werden entweder die Grenze der Handlung treffen, oder sie werden enden, wenn
Sie treffen eine Zelle der Handlung, die bereits eine Flugbahn hat. Das bedeutet
Ihre ersten Samen werden länger wachsen und Ihre späteren Samen werden sich neigen
durch vorherige eingeschränkt werden. Einige der späteren Samen können nicht wachsen
überhaupt. Die Standard-Seeding-Strategie besteht darin, in jeder Zelle einen Seed zu pflanzen,
Das ist ziemlich anstößig, wenn Sie eine hohe Dichte haben. Es bestellt auch
sie, indem sie Samen zuerst entlang der Grundstücksgrenzen pflanzen und sich nach innen winden.
Dies ist möglicherweise nicht ideal für Ihren speziellen Fall. Ich fand das sehr einfach
Strategie für Ihr Beispiel war, nur ein paar Samen zwischen denen zu pflanzen
zwei Punkte der Geschwindigkeit Null, y = 0 und x von -10 bis 10. Diese Trajektorien
wachsen Sie voll und füllen Sie den größten Teil der Handlung ohne Unordnung.
So erstelle ich die Saatpunkte und setze die Dichte:
%Vor% Und so ändere ich die Aufrufe von streamplot
:
Das Ergebnis sieht im Grunde wie das Original aus, aber mit glatteren Farbübergängen und nur 15 Stream-Linien. (Entschuldigung keine Reputation zum Inline-Bild)
Ich denke, Ihre beste Wette ist, eine andere Colormap als Jet zu verwenden. Vielleicht cmap=plt.cmap.plasma
.
Wierd schauende Graphen verdecken das Verständnis der Daten.
Für Daten, die in irgendeiner Weise geordnet sind, wie in diesem Fall durch die Geschwindigkeitsvektorgröße, werden gleichmäßig aufeinanderfolgende Farbabbildungen immer glatter aussehen. Die Helligkeit der sequentiellen Karten variiert monoton über den Farbbereich und entfernt große wahrgenommene Farbänderungen über kleine Datenbereiche. Die einheitlichen Karten variieren linear über ihren gesamten Bereich, wodurch die Hauptmerkmale in den Daten viel mehr sichtbar erscheinen.
Wahrnehmungsgleiche sequenzielle Farbkarten http://matplotlib.org/_images/lightness_00.png
Die Jet-Colormap überspannt mit ihrer Flexion in der Mitte sehr unterschiedliche Helligkeiten. Dies ist für den besonders ungeheuerlichen Übergang von Rot zu Blau um den mittleren Bereich des Graphen verantwortlich.
Jet und andere nicht sequentielle Farbkarten http://matplotlib.org/_images/lightness_05.png
Das matplotlib-Benutzerhandbuch zur Auswahl einer Farbkarte bietet einige Empfehlungen für die Auswahl einer geeigneten Karte für bestimmte Daten einstellen.
Ich denke nicht, dass es noch viel mehr gibt, was Sie tun können, um dies zu verbessern, indem Sie nur die Parameter in Ihrer Handlung ändern.
Der Streamplot unterteilt den Graphen in Zellen mit 30*density[x,y]
in jede Richtung, höchstens eine Stromlinie durchläuft jede Zelle. Die einzige Einstellung, die direkt die Anzahl der Segmente erhöht, ist die Dichte des Gitters, das matplotlib verwendet. Durch Erhöhen der Y-Dichte wird die Segmentlänge verringert, so dass der mittlere Bereich reibungsloser übergehen kann. Die Kosten dafür sind eine unvermeidliche Unordnung der Grafik in Regionen, in denen die Stromlinien horizontal sind.
Sie könnten auch versuchen, die Geschwindigkeiten anders zu normalisieren, so dass die Änderung in der Nähe des Zentrums künstlich verringert wird. Am Ende des Tages scheint es, als ob es die Spitze des Graphen besiegt. Die Grafik sollte eine nützliche Ansicht der Daten für einen Menschen liefern, um zu verstehen. Wenn man eine Colormap mit seltsamen Flexionen verwendet oder die Daten so verzerrt, dass sie besser aussehen, wird das Verständnis, das man sonst aus dem Blick auf den Graphen erhalten könnte, entfernt.
Eine ausführlichere Diskussion über die Probleme mit Colormaps wie Jet finden Sie auf dieser Blog .
Tags und Links python matplotlib numpy