Matlab nach Python übersetzen imagesc

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Cotylaeus
User
Beiträge: 8
Registriert: Montag 27. Januar 2020, 17:59

Hallo Zusammen

Ich sitze wiedereinmal vor Matlab und Python und versuche Matlab code nach Python zu übersetzten und komme nicht weiter. Folgend der Matlab code, bei welchem ich als erstes einen Datensatz einlese. Ich komme bei den beiden verschachtelten for-Schleifen nicht weiter. Matlab gibt mit für die Variable datacube ein 1x216x214 double raus.

xstart=66;
ystart=11;
xend=281;
yend=102;
xn=xend-xstart+1;
yn=yend-ystart+1;
wavelength=data(:,1);
for jj=1:yn
for kk=1:length(wavelength);
datacube(jj,1:xn,kk)=data(kk,(jj-1)*xn+2:(jj-1)*xn+xn+1)
end
end

plotindex1=83;
plotindex2=224;
figure(1)
subplot(2,1,1)
imagesc(datacube(:,:,plotindex1))
axis equal
title([num2str(wavelength(plotindex1)) ' nm'])
subplot(2,1,2)
imagesc(datacube(:,:,plotindex2))
axis equal
title([num2str(wavelength(plotindex2)) ' nm'])

Hier mein Code in Python:

# define variables
x_start = 66
y_start = 11
x_end = 281
y_end = 102
x_n = x_end - x_start + 1
y_n = y_end - y_start + 1
wavelength = data[:, 0]

# calculations
for jj in range(0, y_n):
for kk in range(0, len(wavelength)):
datacube = np.array(data[kk, (jj - 1) * x_n + 2: (jj - 1) * x_n + x_n + 1])

plotindex_1 = 83
plotindex_2 = 224

plt.figure()
plt.subplot(2, 1, 1)
plt.Axes.imshow(extent=[0, 0, plotindex_1])

Wie genau muss ich die Vorschlaufen mache, damit ich das selbe erhalte wie in MatLab und wie genau kann ich den matlabbefhel imagesc nach Python übersetzt? Ich habe mit plt.Axes.imshow versucht komme aber nicht weiter.

Herzlichen Dank für die Hilfe.

Retus
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Als erstes solltest Du die Warnung in Matlab reparieren, nämlich dass sich datacube in jedem Schleifendurchgang vergrößert. Dann hast Du schon ein vor-reserviertes Array, das Du so auch einfach nach Python übersetzen kannst. Dort erzeugst Du nämlich in jeder Schleife einen neuen.
Dann solltest Du die Indizes richtig verrechnen. Das jj-1 kommt ja nur daher, dass in Matlab jj von 1 ab läuft, in Python ist es aber ab 0.
Ähnlich mußt Du auch alle anderen Indizes richtig berechnen.
Wenn man das ganze aber anschaut, dann ist das nur ein reshape mit vielleicht einem swapaxes. Warum das in Matlab so kompliziert geschrieben wurde, wundert.
Wo genau gefällt Dir imshow nicht?
Cotylaeus
User
Beiträge: 8
Registriert: Montag 27. Januar 2020, 17:59

Von welcher Warnung sprichst du genau? Ich erhalte keine. Die Indizes passe ich in dem Fall noch an.
Ich habe keine Ahnung weshalb es so in Matlab gemacht wurde, da ich den Code nicht selber geschrieben habe und versuche diesen zu verstehen. Wie würdest du es denn umsetzten?

Ich weiss nicht wie ich imshow nutzen soll, damit ich das selbe heraus bekomme wie Matlab...
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Entweder ist das nicht der komplette Code, oder aber Du übersiehst die roten Kringel unter `datacube` in Matlab.
Die Dimensionen von datacube sind yn x xn x length(wavelength) und dieses Feld mußt Du in Python vorreservieren. In Matlab geschieht dies automatisch, aber eben mit der erwähnten Warnung, dass man das nicht tun sollte.
Der erste Schritt sollte also immer sein, das Matlab in eine Form zu bringen, wo es leicht nach Python übersetzbar ist, weil Du dann mit den schon existierenden Tests in Matlab schauen kannst, ob das "bessere" Matlab noch die selben Ergebnisse liefert (Falls noch keine Tests in Matlab existieren, ist der 0te Schritt, Tests in Matlab zu schreiben und diese nach Python zu übersetzen).
Bei Deinem Beispiel also, ersteinmal das Feld vorreservieren:

Code: Alles auswählen

datacube = zeros(yn, xn, length(wavelength));
Dann sich die Schleife anschauen und merken, dass die innerste Schleife überflüssig ist:

Code: Alles auswählen

for jj=1:yn
   datacube(jj,:,:)=data(:,(jj-1)*xn+2:(jj-1)*xn+xn+1)';
end
Dann sieht man, dass die Schleife immer Blöcke der Länge xn ausschneidet und zwar vom Index 2 ab. Und zwar yn Stück.

Code: Alles auswählen

used = data(:, 2:yn*xn+1)
Der lange Vektor yn*xn wird nun aber als Matrix der Form xn x yn gebraucht, also benutzt man `reshape`:

Code: Alles auswählen

reshaped = reshape(data(:, 2:yn*xn+1), [length(wavelength),xn,yn])
Die Reihenfolge der Dimensionen ist aber eine andere, man braucht also noch permute:

Code: Alles auswählen

datacube = permute(reshape(data(:,2:yn*xn+1),[length(wavelength),xn,yn]), [3,2,1])
Der Indexzugriff in Python ist um 1 verschoben, reshape heißt dort reshape und permute dort transpose:

Code: Alles auswählen

datacube = data[:, 1:yn*xn+1].reshape(data.shape[0], xn, yn).transpose([2,1,0])
Damit sind die Schleifen eliminiert, so wie es sein sollte (sowohl in Matlab als auch in Python).

Und was meinst Du genau mit "das selbe wie Matlab"? Was gefällt Dir an imshow nicht?
Cotylaeus
User
Beiträge: 8
Registriert: Montag 27. Januar 2020, 17:59

Das hat super geklappt. Ich danke dir herzlichst.

Nun zu Imagesc oder eben imshow:

Der Code in Matlab ist:

imagesc(datacube(:,:,plotindex1))

Es ist nicht, dass mir Imshow nicht gefällt sondern ich nicht herausbekomme wie ich es nutzen kann. Ich kann dir leider kein Bild verlinken, da ich nichts ähnliches gefunden habe und ich ja kein eigenes hochladen kann.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du die Dokumentation und Beispiele in der Matplotlib-Dokumentation zu imshow angeschaut?
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Cotylaeus: Bilder kann man beispielsweise bei imgur.com hochladen und dann hier im Forenbeitrag verlinken.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Cotylaeus
User
Beiträge: 8
Registriert: Montag 27. Januar 2020, 17:59

Also so sollte es aussehen:
Bild

Ich habe die imshow dokumentation angeschaut und bin nicht richtig schlau geworden. :/
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Was verstehst Du am ersten Beispiel hier nicht?
Cotylaeus
User
Beiträge: 8
Registriert: Montag 27. Januar 2020, 17:59

Also ich habe mir die Beispiele nochmals zu herzen genommen und mein Code an den Beispielen orientiert. Nun Sieht der Code so aus:
fig, ax = plt.subplots()
im = ax.imshow(datacube, cmap=cm.RdYlGn, origin='upper')
plt.show()

Jedoch erhalte ich nun folgende ErrorMessage:

TypeError: Invalid shape (92, 216, 256) for image data
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie denkst Du, werden dreidimensionale Daten auf einem zweidimensionalen Bildschirm dargestellt?
Das ist ja auch nicht das, was in Matlab steht.
Antworten