Balkendiagramm in Matplotlib mit einer Farbkarte

Sep 25 2020

Ich habe eine df mit zwei Spalten:

  • y: verschiedene numerische Werte für die y-Achse
  • Tage: die Namen von vier verschiedenen Tagen (Montag, Dienstag, Mittwoch, Donnerstag)

Ich habe auch eine Farbkarte mit vier verschiedenen Farben, die ich selbst erstellt habe, und es ist ein ListedColorMap-Objekt.

Ich möchte ein Balkendiagramm mit den vier Kategorien (Wochentagen) auf der x-Achse und den entsprechenden Werten auf der y-Achse erstellen. Gleichzeitig möchte ich, dass jeder Balken mithilfe meiner Farbkarte eine andere Farbe hat.

Dies ist der Code, mit dem ich mein Balkendiagramm erstellt habe:

def my_barchart(my_df, my_cmap):
  fig = plt.figure()
  ax = fig.add_axes([0,0,1,1])
  ax.bar(my_df['days'], my_df['y'], color=my_cmap)
  return fig

Ich erhalte jedoch die folgende Fehlermeldung: "Objekt vom Typ 'ListedColormap' hat kein len ()", daher scheint es, dass ich my_cmap nicht richtig verwende.

Wenn ich das aus der Funktion entferne und ausführe, sieht mein Balkendiagramm in Ordnung aus, außer dass alle Balken dieselbe Farbe haben. Meine Frage lautet also: Wie kann man eine Farbkarte mit einem Balkendiagramm richtig verwenden?

Antworten

4 JakeLevi Sep 25 2020 at 17:29

The color argument wants either a string or an RGB[A] value (it can be a single colour, or a sequence of colours with one for each data point you are plotting). Colour maps are typically callable with floats in the range [0, 1].

So what you want to do is take the values you want for the colours for each bar, scale them to the range [0, 1], and then call my_cmap with those rescaled values.

So, say for example you wanted the colours to correspond to the y values (heights of the bars), then you should modify your code like this (assumes you have called import numpy as np earlier on):

def my_barchart(my_df, my_cmap):
    rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))

    fig = plt.figure()
    ax = fig.add_axes([0,0,1,1])
    ax.bar(my_df['days'], my_df['y'], color=my_cmap(rescale(my_df['y'])))
    return fig

Here is a self-contained minimal example of using the color argument with the output from a cmap:

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])

my_cmap = plt.get_cmap("viridis")
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))

plt.bar(x, y, color=my_cmap(rescale(y)))
plt.savefig("temp")

Output:

aprendiz Sep 25 2020 at 17:45

Okay, I found a way to do this without having to scale my values:

def my_barchart(my_df, my_cmap):
  fig = plt.figure()
  ax = fig.add_axes([0,0,1,1])
  ax.bar(my_df['days'], my_df['y'], color=my_cmap.colors)
  return fig

Simply adding .colors after my_cmap works!