Matplotlib und Colorbar

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
JonDo
User
Beiträge: 5
Registriert: Mittwoch 13. März 2013, 15:01

Hallo allerseits,
ich kämpfe schon seit längerem mit einem Colorbar-Problem:
Ich möchte Links eine Grafik und rechts davon die Colorbar haben. Derzeit verzerrt mir aber die Colorbar die eigentliche Grafik:
Bild
hier ist der Sourcecode dazu:

Code: Alles auswählen

'''
Created on 06.03.2013

@author: 
'''

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.ticker import NullLocator



def phases(tls, maxWeight=None, ax=None):

    if not ax:
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)

    if not maxWeight:
        maxWeight = 2**np.ceil(np.log(np.abs(tls).max())/np.log(2))
    
    minarray = []
    for arrays in tls:
        minarray.append(min(arrays))
    
    ax.patch.set_facecolor('white')
    ax.set_aspect('equal', 'box')
    ax.xaxis.set_major_locator(NullLocator())
    ax.yaxis.set_major_locator(NullLocator())
    cmap = plt.get_cmap('PuBu')
    print min(minarray)
    

    y=0
    for i in tls:
        x=0
        y+=1
        for j in i:
            x+=1
            color = cmap(interpolateZeroOne(min(minarray), 1.0,j))
            if j == 1.001: color = 'white'
            size = 1 #np.sqrt(np.abs(interpolateZeroOne(min(minarray), 1.0,j)))
            rect = Rectangle([x - size / 4, y - size / 4], size, size, facecolor=color, edgecolor='black')
            ax.add_patch(rect)
            ax.autoscale_view()
            
    ax.set_ylim(*ax.get_ylim()[::-1])
    
    data = tls
    cax = ax.imshow(data, interpolation='nearest', cmap=plt.get_cmap('PuBu'))

    cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
    cbar.ax.set_yticklabels(['< -1', '0', '> 1'])



def interpolateZeroOne(minV, maxV, value):
    return maxV/(maxV-minV)*(value-minV)

if __name__ == '__main__':
    allCorrP = [[1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.997, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.959, 0.956, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.814, 0.804, 0.919, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [-0.122, -0.139, 0.124, 0.473, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.332, 0.323, 0.546, 0.813, 0.878, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.784, 0.767, 0.886, 0.988, 0.502, 0.821, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.832, 0.826, 0.938, 0.996, 0.439, 0.79, 0.976, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.782, 0.778, 0.904, 0.994, 0.506, 0.843, 0.979, 0.992, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001, 1.001], [0.821, 0.814, 0.932, 0.996, 0.459, 0.8, 0.981, 0.997, 0.992, 1.0, 1.001, 1.001, 1.001, 1.001, 1.001], [0.859, 0.85, 0.947, 0.995, 0.397, 0.762, 0.981, 0.995, 0.986, 0.995, 1.0, 1.001, 1.001, 1.001, 1.001], [0.265, 0.24, 0.471, 0.763, 0.908, 0.959, 0.799, 0.731, 0.774, 0.748, 0.71, 1.0, 1.001, 1.001, 1.001], [0.35, 0.344, 0.56, 0.823, 0.865, 0.997, 0.826, 0.801, 0.854, 0.81, 0.773, 0.949, 1.0, 1.001, 1.001], [0.785, 0.768, 0.886, 0.987, 0.497, 0.817, 0.997, 0.977, 0.977, 0.98, 0.981, 0.799, 0.823, 1.0, 1.001], [0.795, 0.788, 0.914, 0.996, 0.494, 0.83, 0.981, 0.996, 0.996, 0.996, 0.991, 0.772, 0.84, 0.981, 1.0]]
    phases(allCorrP)
    plt.show()
ich weiß echt nicht mehr weiter und würde mich über eure Unterstützung sehr freuen!
Danke schon einmal im Voraus!

ps: ich weiß nicht genau, in welche Kategorie das fällt, daher poste ich es mal unter Allgemeines
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Hallo und Willkommen im Forum,

Ich muss sagen ich habe deinen Code nicht auf Anhieb verstanden und auch nicht weiter versucht das zu tun, aber ich denke hier mit:
JonDo hat geschrieben:

Code: Alles auswählen

    y=0
    for i in tls:
        x=0
        y+=1
        for j in i:
            x+=1
            color = cmap(interpolateZeroOne(min(minarray), 1.0,j))
            if j == 1.001: color = 'white'
            size = 1 #np.sqrt(np.abs(interpolateZeroOne(min(minarray), 1.0,j)))
            rect = Rectangle([x - size / 4, y - size / 4], size, size, facecolor=color, edgecolor='black')
            ax.add_patch(rect)
            ax.autoscale_view()
wolltest du eigentlich das hier schreiben?!:

Code: Alles auswählen

    for y, i in enumerate(tls):
        for x, j in enumerate(i):
            color = cmap(interpolateZeroOne(min(minarray), 1.0,j))
            if j == 1.001: color = 'white'
            size = 1
            rect = Rectangle([x, y], size, size, facecolor=color, edgecolor='black')
            ax.add_patch(rect)
            ax.autoscale_view()
Du hast da denke ich einen Logik Fehler gemacht mit dem erstellen von y = 0 und dem sofortigen hochzählen durch y += 1 ?

Des Weiteren bringt der Code `data = tls` nichts, es wird keine Kopie erstellt, es handelt sich immer noch um das selbe Objekt

Ich verstehe nicht was du genau meinst mit verzerren? Du meinst wenn du folgenden Code entfernst sieht es richtig aus? Wenn nicht dann ist es "verzerrt"?
JonDo hat geschrieben:

Code: Alles auswählen

cax = ax.imshow(data, interpolation='nearest', cmap=plt.get_cmap('PuBu'))

cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
 cbar.ax.set_yticklabels(['< -1', '0', '> 1'])
JonDo
User
Beiträge: 5
Registriert: Mittwoch 13. März 2013, 15:01

Hi und danke schonmal für deine Antwort.
Ja, du hattest recht, das wollte ich schreiben. Bin noch relativ neu in Python und etwas unerfahren.
Also was ich mit verzerrt meine, seiht man, wenn man

Code: Alles auswählen

    data = tls
    cax = ax.imshow(data, interpolation='nearest', cmap=plt.get_cmap('PuBu'))

    cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
    cbar.ax.set_yticklabels(['< -1', '0', '> 1'])
auskommentiert. Damit ist die Grafik links nicht verzerrt und natürlich tut auch

Code: Alles auswählen

data=tls
nix, das ist ein Relikt aus meinen Versuchen.
Viele Grüße
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Code: Alles auswählen

    cax = ax.imshow(tls, interpolation="nearest")
    cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
    cbar.ax.set_yticklabels(['< -1', '0', '> 1'])
Veränder mal die letzen Zeilen so und entferne die Colormap dann wirst du sehen was passiert.

1. erzeugst du jedes Rechteck manuell mit Patch, was dann eine Überlagerung des eigentlichen Graphen ist.
2. erzeugst du einen Graphen und erstellst mit den Daten dann eine Skala

Ich kenne mich mit matplotlib nicht besonders aus, aber ich halte den "ax.add_patch" Ansatz für einen ganz falschen Weg. Warum zeichnest du deine Daten nicht so?

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt

M = np.array(((1,1),(2,3)))
plt.imshow(M, interpolation="nearest")
plt.show()
JonDo
User
Beiträge: 5
Registriert: Mittwoch 13. März 2013, 15:01

ok, vermutlich hast du recht, dass Patch nicht die richtige Lösung ist...
Ich habe in Matplotlib eben auch noch sehr begrenzte Erfahrungen.
Bei der Zeichnung der Rechtecke habe ich sehr viel aus dem Beispiel mit Hinton-Diagrammen übernommen:
http://matplotlib.org/examples/api/hinton_demo.html
Jetzt weiß ich leider nicht, wie ich das Ganze auf dem imshow-Weg realisiere. Kannst du mir da nochmal helfen?
VIELEN DANK!!!
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Wie man Achsen formatiert, beschriftet oder Limits fest legt, hast du in deinem Code ja schon oft gemacht. Eine Matrix zu plotten ist auch keine Kunst. Du musst nur deine Daten aus allCorrP in eine numpy Array packen.

Code: Alles auswählen

matrix = np.array(allCorrP)
# dann evtl. noch die daten ersetzetn die dir nicht gefallen und was auch immer.
matrix[matrix == 1.001] = None
plt.imshow(matrix, interpolation="nearest", cmap="PuBu")
plt.show()
JonDo
User
Beiträge: 5
Registriert: Mittwoch 13. März 2013, 15:01

Oh wow - das geht ja viel einfacher. Ich hab noch viel zu lernen :-)
Ich kann mich nur wiederholen: MERCI! Ich muss das Ding nämlich recht zeitnah haben...

Wenn ich nun folgendes schreibe:

Code: Alles auswählen

    
    matrix[matrix == 1.001] = None
    fig = plt.figure()
    cax = plt.imshow(matrix, interpolation="nearest", cmap="PuBu")
    cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
    cbar.ax.set_yticklabels(['< -1', '0', '> 1'])
    plt.show()
Dann habe ich ja fast schon, was ich will. Weißt du zufällig, wie ich die "Ränder" wiederbekomme?
Eine Frage für das Verständnis: was macht eigentlich

Code: Alles auswählen

interpolation="nearest"
?
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

JonDo hat geschrieben:Weißt du zufällig, wie ich die "Ränder" wiederbekomme?
Genau so wie sie vorher waren, kA.
Generell kann man mittels plt.grid(True), ein Raster einblenden welches sich nach den Achsenbeschriftungen richtet.
JonDo hat geschrieben:Eine Frage für das Verständnis: was macht eigentlich

Code: Alles auswählen

interpolation="nearest"
?
Das finde ich ohne Bilder bzw Diagramm schwer zu erklären. Schau mal in der Dokumentation zu imshow, was interpolation alles für Werte entgegen nimmt und probier ein paar aus. Wikipedia hat dafür ein paar Beispiele, schau dir die Seite mal an. Sinn ist zu beschreiben wie die Lücken überbrückt werden sollen, falls man das so sagen darf.
JonDo
User
Beiträge: 5
Registriert: Mittwoch 13. März 2013, 15:01

Hi,
ich wollte mich nochmal bedanken!
Mit deiner Hilfe habe ich es jetzt hinbekommen!
Viele Grüße
Antworten