matplotlib und colormap

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
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

Hallo zusammen,

ich möchte mithilfe von matplotlib einen Scatterplot plotten. Das klappt soweit auch schon ganz gut. Momentan haben alle Punkte die gleiche Farbe. Ich möchte nun eine der vorhandenen colormaps nutzen (die RdYlGn). Allerdings hab ich keine Ahnung wie ich die einbinden kann. Hier erst mal mein Beispiel:

Code: Alles auswählen

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)

N = len((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15))
ind = np.arange(N)
ax.scatter(ind, (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), marker = 'o', color = 'darkred')
plt.xticks(ind,(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) )
ax.set_xlabel('x-Achse')
ax.set_ylabel('Y-Achse')
ax.grid(False)
plt.show
In der Dokumentation steht, dass man mit

Code: Alles auswählen

from matplotlib.pyplot import colormaps
und dem Aufruf

Code: Alles auswählen

imshow ( x-Achse, cmap = cm.hot )
(hot ist hier eine solche colormap) zum Ziel kommen kann.

Ich hatte es jetzt so versucht:

Code: Alles auswählen

ax.scatter(ind, (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), marker = 'o', color = imshow((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), cmap = cm.hot))
versucht. Da kommt aber dann die Fehlermeldung

Code: Alles auswählen

TypeError: Invalid dimensions for image data
Hat jemand eine Idee wa sich falsch mache?

Gruß Isa
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Hi,

schau mal die Dokumentation von "plt.scatter". Dort findest du die Antwort:

Code: Alles auswählen

    Keyword arguments:   
      *c*:
        a color. *c* can be a single color format string, or a
        sequence of color specifications of length *N*, or a
        sequence of *N* numbers to be mapped to colors using the
        *cmap* and *norm* specified via kwargs (see below). Note
        that *c* should not be a single numeric RGB or RGBA
        sequence because that is indistinguishable from an array
        of values to be colormapped.  *c* can be a 2-D array in
        which the rows are RGB or RGBA, however.
Grüße
Gerrit
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

Hallo Gerrit.

erstmal danke für Deine Antwort. Ich habe da aber doch noch eine Frage.
Um ganz ehrlich zu sein, habe ich trotzdem nicht ganz verstanden, was genau ich falsch gemacht habe. Mit 'cmap' zu arbeiten scheint ja nicht ganz falsch zu sein. Was genau ist denn an meinem Aufruf der Colormap falsch?

------------------------Update-----------------------
Ich habe es gerade so gemacht:

Code: Alles auswählen

ax.scatter(ind, (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), marker = 'o', cmap = cm.RdYlGn)
Er meckert jetzt zwar nicht mehr, nachdem ich dann auch

Code: Alles auswählen

from matplotlib import cm
importiert habe. Allerdings setzt er die Colormap nicht um. Ich hab keine Ahnung, was ich falsch mache.

Gruß Isa
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

Also ich denke, dass ich jetzt die Lösung gefunden habe und möchte sie mit euch teilen.

Code: Alles auswählen

fig = plt.figure()
ax = fig.add_subplot(111)
N = len(x_and_y_axis_content)
radius = np.arange(N)
area = radius
x_axis = radius
y_axis = area
cmap = plt.get_cmap('RdYlGn')
sc_plot = plt.scatter(x_axis, y_axis, marker = scatter_marker, c = radius, cmap = cmap )
ax.set_xlabel(x_axis_label)
ax.set_ylabel(y_axis_label)
ax.grid(False)
plt.colorbar()
plt.show()
Ich weiss nicht, ob das jetzt die schönste Lösung ist, aber es ist eine :)
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

maria_dolores hat geschrieben: Ich habe es gerade so gemacht:

Code: Alles auswählen

ax.scatter(ind, (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), marker = 'o', cmap = cm.RdYlGn)
das funktioniert nicht, weil du das 'c' Keywords vergessen hast, so geht es:

Code: Alles auswählen

ax.scatter(ind, (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), c=range(15), marker = 'o', cmap = cm.RdYlGn)
Noch etwas, du weisst schon dass, '(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)' das selbe ist wie 'range(1,16)'?
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

@ DaMutz: Danke, ich wusste das mit dem range noch nicht.

Ich habe jetzt nochmal eine Frage. Wenn ich bei einem Scatterplot eine Legende hinzufügen möchte, die aber nicht auf einer Colormap basiert, sondern auf Farben, die ich selbst definiert habe, wie kann ich die denn einfügen?

Hier mein Beispielcode:

Code: Alles auswählen

import matplotlib.pyplot as plt

x = range(-10,10)
y = range(-10,9)
leg = []
colors = ['#3E0000', '#660000', '#9D0000', '#DD0000', '#FF4A4A', '#FF8484', '#FFB3B3', '#FEFFF2', '#C6FEBC', '#95FE83', '#26EF03', '#1DB002', '#147E01', '0E5801', '#0A3A01', '#004000' ]

for i in x:
    if i in range(-10,-5):
        plt.scatter(x[i], y[i], marker = 'o', s = 150, c = colors[i-1])
    if i in range(-5,-3):
        plt.scatter(x[i], y[i], marker = 'o', s = 150, c = colors[i-1])
    if i in range(-3, 0):
        plt.scatter(x[i], y[i], marker = 'o', s = 150, c = colors[i-1])
    if i in range(0, 3):
        plt.scatter(x[i], y[i], marker = 'o', s = 150, c = colors[i-1])
    if i in range(3, 6):
        plt.scatter(x[i], y[i], marker = 'o', s = 150, c = colors[i-1])
    if i in range(6, 10):
        plt.scatter(x[i], y[i], marker = 'o', s = 150, c = colors[i-1])
    leg.append(colors[i-1])
    plt.legend(leg)
plt.show()
Die 'Legendenfarben' werden quasi doppelt und dreifach ausgegeben. Ich sehe meinen Fehler nicht.

Kann mir vielleicht jemand helfen oder einen Tipp geben?

Gruß
Isa
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

Hallo Isa

was ist den dein Ziel am Schluss? Bei deinem jetzigen Plot sagen doch die Farben nichts aus?

diese Zeile kannst du eleganter schreiben:

Code: Alles auswählen

if i in range(-10,-5):
nämlich so:

Code: Alles auswählen

if -10 <= i < -5:
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

Hallo DaMutz,

sorry, dass ich jetzt erst antworte.
Mein Ziel ist es am Ende scatter zu haben, die je nach Wert eine andere Farbe haben. Soll also ein scatter geplottet werden, der zB den 'Wert' -8 hat, dann soll er die erste Farbe in der Liste der Farben bekommen. Hat ein Scatter den 'Wert' -4, dann bekommt er die zweite Farbe aus der Liste und so weiter. Und danke für die Info. Ich habe das mit dem range gleich umgeschrieben.

Grüßle Isa
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

Code: Alles auswählen

import matplotlib
import matplotlib.pyplot as plt
import random

fig = plt.figure()
ax = fig.add_subplot(111)
N = (10)

x = range(0,200)
y = [random.randint(-10, 10) for _ in x]

#~ cmap = matplotlib.colors.ListedColormap ( [[1, 0, 0], [0, 1, 0]])
cmap = matplotlib.colors.ListedColormap (['#3E0000', '#660000', '#9D0000', '#DD0000', '#FF4A4A', '#FF8484', '#FFB3B3'])

#~ norm = matplotlib.colors.BoundaryNorm([0], cmap.N)
norm = matplotlib.colors.BoundaryNorm([-5, -3, 0, 3, 6, 10], cmap.N)

ax.scatter(x, y, c=y, marker = 'o', cmap = cmap, norm=norm)
plt.show()
du musst eine Colormap und eine Norm definieren. Dann klappt das gut. In diesem Fall werden die Zahlen < -5 mit der 1. Farbe gezeichnet; die Zahlen zwischen -5 und -3 werden mit der 2. Farbe gezeichnet; usw.

Wenn du den auskommentierten Teil aktivierst, dann hast du die Grenze bei 0 und alles was grösser ist wird grün, was kleiner ist wird rot. Der 0 Punkt, da weiss ich nicht wie der wird. Aber das kannst du ja ausprobieren.

Hier ist noch ein weiteres Beispiel:
http://www.scipy.org/Cookbook/Matplotli ... oloredLine
maria_dolores
User
Beiträge: 39
Registriert: Dienstag 10. August 2010, 12:38

Das hat mir so sehr weitergeholfen. Vielen vielen Dank.

Grüßle
Isa
Antworten