Numpy Histogram2d

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rtbone
User
Beiträge: 6
Registriert: Mittwoch 29. August 2012, 12:55

Hallo Community,

ich hab eine Frage bei der Erstellung von 2d Histogrammen mit Hilfe von numpy. Mit einem Datensatz in einem Definitionsbereich von x in [0,5] und y in [0,5] könnte ich z.B. ein 5x5 Histogramm erstellen, also in jeder Dimension ein Intervall mit Delta x, Delta y=1, somit 25 einzelne bins.

Nun, ich möchte jedoch für jedes y- Intervall verschiedene Bingrößen in x Richtung haben. Beispielsweise könnte es so aussehen: Ich plotte mit mein Histogram und habe in y-Richtung 5 Intervalle. In x-Richtung jedoch pro Intervall verschieden große bins. Z.b: erst 5 bins, dann 4, dann 3, etc.

Ich würde mich freuen, wenn mir eine erklären könnte, wie es funktioniert. Aus der numpys Doku wurde ich nicht schlau.

Gruß,

rtbone
deets

Musst du nicht einfach deine Daten entlang der y-Bin-Grenzen die du haben willst filtern, und darauf dann ein Histogramm mit der entsprechenden X-Anzahl machen?
rtbone
User
Beiträge: 6
Registriert: Mittwoch 29. August 2012, 12:55

Hallo deets,

ja genau. Ich hab praktisch eine feste "Binanzahl" in y-Richtung. Jedoch muss jede Anzahl von x-Bins pro y- Intervall (ich stelle mir das immer als Streifen durch den Graphen vor) unterschiedlich sein.

Grüße,

rtbone
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Ich habe es nur kurz in der Doku nachgeschlagen, aber das Ergebnis sieht korrekt aus:

Code: Alles auswählen

>>> import numpy as np
>>> bx, by = np.array([0, 10, 20, 100]), np.array([0, 30, 50, 100])
>>> xs, ys = zip(*[(x, y) for x in range(100) for y in range(100)])
>>> np.histogram2d(xs, ys, [bx, by])
(array([[  300.,   200.,   500.],
       [  300.,   200.,   500.],
       [ 2400.,  1600.,  4000.]]), array([   0.,   10.,   20.,  100.]), array([   0.,   30.,   50.,  100.]))
Das Leben ist wie ein Tennisball.
rtbone
User
Beiträge: 6
Registriert: Mittwoch 29. August 2012, 12:55

Hallo EyDu,

soweit ich das richtig verstehe, kommt bei dir ein 3x3 histogram heraus? An sich arbeite ich an einer Form, bei der am Ende etwas rauskommt, wie:

Code: Alles auswählen

hist=[[1],[1,2],[1,2,3]]
Z.b: ist die erste Zeile zwischen x=0 bis 1
die Zweite ist dann zwischen x=0 bis 0.5 und dann von 0.5 bis 1
die letzte Zeile "drittelt" die Zeile.

auf dem Graphen sehe ich dann ein quadratischess, color-coded histogram eingeteilt in 3 Teile (in y-Richtung), wobei das erste dann ein langer Streifen ist, der zweite Teil besteht dann aus 2 Teilen, der letzte aus 3.

rtbone
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ok, da habe ich dich wohl falsch verstanden. Das könnte daran liegen, dass diese Anforderung doch recht ungewöhnlich ist. Was genau hast du denn damit vor? Mir fällt dazu keine passende Anwendung ein. Fünf verschiedene Auflösungen über den selben Daten macht für noch Sinn, aber fünf Auflösungen für fünf verschiedene Daten nicht mehr.

Ich würde mal behaupten, dass numpy dazu keine passende Funktion hat, weil dieses Szenarion etwas seltsam ist. Ich würde einfach per Hand fünf eindimensionale Histogramme mit den fünf Auflösungen erstellen. Das führt aber wieder zum ersten Absatz ^^
Das Leben ist wie ein Tennisball.
rtbone
User
Beiträge: 6
Registriert: Mittwoch 29. August 2012, 12:55

Nun ich habe eine "hässliche" Lösung gefunden.

Beispielsweise habe ich so ein Histogram:

Code: Alles auswählen

hist=[[0,1,0,1],[0,1,0,0],[1,2,3,4]]
Und will nun eine 4,2,1 Einteilung, dann mache ich:

Code: Alles auswählen

hist=[[2,2,2,2],[1,1,0,0],[1,2,3,4]]
Im Plot wird dann der Eindruck erweckt, es wären dann einzelne, zusammenhängende Flächen.

Nun ich brauche diese komische Einteilung, da ich etwas auf einer Karte projizieren möchte, und da es etwas krummlinig wird man noch alles auf eine Projektion mappen muss, brauche ich solche Histogramme (lange komplizierte Geschichte).

rtbone
rtbone
User
Beiträge: 6
Registriert: Mittwoch 29. August 2012, 12:55

Hallo nochmal,

kann man mein Problem vllt. mit einem anderen Befehl aus numpy und matplotlib lösen?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Ich kann mir kaum vorstellen, dass es dafür einen Operator gibt, die Funktion ist einfach ein wenig zu abwegig. Worum geht es dir bei der Projektion auf eine Karte denn genau, bzw. was sollen die Histogramme darstellen? Angenommen, du hast ein Histogramm pro Zeile, soll dann eine Farbe in Zeile 1 die gleiche Anzahl an Punkten angeben wie eine Zelle in Zeile 2 mit der selben Anzahl? Also im Prinzp: sind die Histogramme unabhängig oder nicht? Wo hast du momentan Probleme? Die Berechnung scheinst du ja zu haben, ist es nur noch eine Frage der Anzeige?
Das Leben ist wie ein Tennisball.
rtbone
User
Beiträge: 6
Registriert: Mittwoch 29. August 2012, 12:55

Nun,

die Einheitskugel hat 4*pi sr, bzw. etwa 40000 Quadratgrad und dies versuche ich nährungsweise darzustellen. Wenn man sich das Gradnetz anguckt, dann passen am Äquator etwa 360 Quadratgradkästchen, aber zu den Polen hin wird es kleiner!

Ich muss wohl leider tricksen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ok, damit kann man doch arbeiten. Ich mache einfach mal einen Gegenvorschlag: Statt zu versuchen die Punkte irgendwie auf eine Fläche zu bekommen und dabei diverse grobe Ungenauigkeiten zu erzeugen, würde ich im Koordinatensystem der Kugel arbeiten. Sagen wir einfach mal, du teilst sowohl den Ost-West-Winkel (alpha) in 360 Schritte auf und den Nord-Süd-Winkel ebenfalls. Für jede Kombination aus alpha und beta berechnest du nun lokal ein Histogramm. Damit die Zellen vergleichbar sind, würde ich als lokale Umgebung einfach einen Kreis nehmen, welcher senkrecht auf die Kugeloberfläche projiziert ist. Das lässt sich ja recht leicht mittels Skalarprodukt rausfinden.

Wie groß "lokal" ist, hängt natürlich ein wenig von deinen Anforderungen ab, ebenso die Form der lokalen Umgebung. Alles andere als ein Kreis macht aber wahrscheinlich wenig Sinn, schon gar nicht würde ich das über die Winkel alpha und beta eingrenzen. Dann hast du das gleiche Problem wieder, an dem du jetzt gerade sitzt. Insgesamt sollte die Implementierung wohl nicht viel länger als 50 Zeilen sein. Ich denke eher, dass es darunter liegt.

Vielleicht passt es ja zu deinen Anforderungen.

Sebastian
Das Leben ist wie ein Tennisball.
Antworten