Datenvisualisierung mit Pandas

Einführung

Pie Charts with Pandas

Es ist selten eine gute Idee, wenn man wissenschaftliche oder geschäftliche Daten nur rein textuell dem jeweiligen Zielpublikum präsentiert. Zur Visualisierung der Daten werden meistens verschiedene Arten von Diagrammen verwendet. Dadurch wird die Kommunikation der Information effizienter und macht die Daten greifbarer. Mit anderen Worten macht es komplexe Daten zugänglicher und verständlicher. So können numerische Daten beispielsweise in Punkt-, Linien-, Säulen- und Balkendiagrammen sowie in Kreis-, Kuchen und Tortendiagrammen grafisch repräsentiert werden.

Wir haben bereits die starken Möglichkeiten von Matplotlib kennengelernt, um öffentlichkeitstaugliche Grafiken zu erstellen. Matplotlib ist ein Low-Level-Werkzeug, um dieses Ziel zu erreichen. Grafiken können noch durch Basiselemente erweitert werden wie beispielsweise Legenden, Bezeichnungen und so weiter. Mit Pandas können all diese Möglichkeiten leichter umgesetzt werden.

Wir beginnen mit einem einfachen Beispiel eines Liniendiagrammes.

Liniendiagramm

Series

Sowohl die Pandas-Series, als auch die DataFrames, unterstüzen die Plot-Methode.

Sie können im folgenden einfaches Beispiel einer Linien-Grafik für ein Series-Objekt sehen. Wir verwenden eine einfache Python-Liste data für die Daten. Der Index wird für die x-Werte verwendet, oder die Domäne.

import matplotlib.pyplot as plt
import pandas as pd

data = [16.2, 16.6, 17.0, 17.3, 17.7, 18.0, 
        18.3, 18.5, 18.3, 18.2, 17.9, 17.3,
        19.1, 19.3, 19.5, 19.8, 19.8, 20.0, 
        20.2, 20.4, 20.6, 20.8, 21.0, 21.2, 
        21.3, 21.5, 21.7, 21.8, 22.0, 22.3]
s = pd.Series(data, index=range(100, 250, 5))

s.plot()
plt.show()
No description has been provided for this image

Es ist möglich die Verwendung des Indexes zu unterdrücken, indem der Parameter use_index auf False gesetzt wird:

s.plot(use_index=False)
plt.show()
No description has been provided for this image

Im vorigen Beispiel bestand der Index aus numerischen Werten. In vielen Fällen besteht der Index jedoch aus Stringwerten. Wir spielen nun mit einem solchen Beispiel:

fruits = ['apples', 'oranges', 'cherries', 'pears']
quantities = [20, 33, 52, 10]
S = pd.Series(quantities, index=fruits)
plt.plot(S)  # notwendig ab Pandas-Version 0.23.4
#S.plot()    # funktioniert bis 0.23.4 
plt.show()
No description has been provided for this image

Natürlich ergibt es wenig Sinn in diesem Fall, d.h. bei kategorialen Daten, ein Liniendiagramm zu benutzen, da die Daten ja keine kontinuierliche Funktion beschreiben. Hier empfiehlt es sich zum Beispiel, ein Säulen-, Balken oder Kreisdiagramm zu benutzen.

DataFrames

Wir stellen nun die Plot-Methode für DataFrames vor. Dazu definieren wir ein Dictionary mit Bevölkerungswerten und Flächenangaben. Dieses Dictionary verwenden wir dann für die Erstellung eine DataFrame-Objektes, welches wir anschliessend für die Grafik verwenden wollen:

# prog4book
monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", 
          "Juli", "August", "September", "Oktober", "November", 
          "Dezember"]
max_temperatur = [17, 16, 17, 19, 23, 25, 28, 28, 27, 24, 21, 18]
durchschnitts_temperatur = [14, 13, 14, 17, 20, 24, 26, 27, 
                            25, 22, 19, 15]
min_temperatur = [10, 9, 11, 14, 18, 22, 25, 26, 24, 19, 15, 12]
niederschlag_mm = [296, 278, 117, 79, 74, 24, 1, 27, 72, 155, 
                   110, 283]

kreta_dict = {"Maximal": max_temperatur, 
              "Durchschnitt":durchschnitts_temperatur, 
              "Minimal": min_temperatur, 
              "Niederschlag": niederschlag_mm}

kreta_df = pd.DataFrame(kreta_dict, index=monate)
print(kreta_df.head(5))
         Maximal  Durchschnitt  Minimal  Niederschlag
Januar        17            14       10           296
Februar       16            13        9           278
März          17            14       11           117
April         19            17       14            79
Mai           23            20       18            74
# prog4web
import pandas as pd

cities = {"Name": ["London", "Berlin", "Madrid", "Rom", 
                   "Paris", "Wien", "Bukarest", "Hamburg", 
                   "Budapest", "Warschau", "Barcelona", 
                   "München", "Mailand"],
          "Bevölkerung": [8615246, 3562166, 3165235, 2874038,
                         2273305, 1805681, 1803425, 1760433,
                         1754000, 1740119, 1602386, 1493900,
                         1350680],
          "Fläche" : [1572, 891.85, 605.77, 1285, 
                    105.4, 414.6, 228, 755, 
                    525.2, 517, 101.9, 310.4, 
                    181.8]
}

city_frame = pd.DataFrame(cities,
                          columns=["Bevölkerung", "Fläche"],
                          index=cities["Name"])
print(city_frame)
           Bevölkerung   Fläche
London         8615246  1572.00
Berlin         3562166   891.85
Madrid         3165235   605.77
Rom            2874038  1285.00
Paris          2273305   105.40
Wien           1805681   414.60
Bukarest       1803425   228.00
Hamburg        1760433   755.00
Budapest       1754000   525.20
Warschau       1740119   517.00
Barcelona      1602386   101.90
München        1493900   310.40
Mailand        1350680   181.80

Der folgende Code erstellt die Grafik unseres DataFrames. Die Flächen-Werte werden noch mit 1000 multipliziert, da die "Flächen"-Linie sonst unsichtbar bzw. durch die x-Achse verdeckt würde:

# prog4book
kreta_df.plot()
Ausgabe:
<Axes: >
No description has been provided for this image
# prog4web
city_frame["Fläche"] *= 10000
city_frame.plot()
plt.show()
No description has been provided for this image

Die Beschriftung der Achsen entspricht nicht unseren Wünschen: Zum einen ist die X-Achse unbeschriftet und zum anderen sind die Werte der Y-Achse in wissenschaftlicher Notation angegeben. Letzeres erkennt man an der Beschriftung le7, die sich oben links oberhalb der Linie befindet. le7 bedeutet, dass die Werte der Y-Achse mit $10^7$ multipliziert werden müssen.

Die X-Achse können wir mit den Städtenamen versehen, indem wir explizit xticks auf den Wert range(len(city_frame.index) setzen. Der Parameter ret ist hierbei auch von besonderer Wichtigkeit. Mit ihm haben wir den Schrägdruck der Städtenamen erreicht, d.h. wir haben die Städtenamen um 60 Grad bezogen auf die Horizontale gedreht. Lässt man ihn weg oder setzt ihn auf Null, dann werden die Städtnamen überlappend gedruckt und damit unlesbar.

# prog4web
import matplotlib
city_frame.plot(xticks=range(len(city_frame.index)),
                rot=60)
plt.gca().yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter('%d')) 

plt.show()
No description has been provided for this image
# prog4book
kreta_df.plot(xticks=range(len(kreta_df.index)),
              rot=75)
Ausgabe:
<Axes: >
No description has been provided for this image

Sekundärachsen (Twin Axes)

Die Flächen-Spalte hatten wir mit 10000 multipliziert, damit sie besser dargestellt werden kann. Die bessere Lösung besteht in der Verwendung von Sekundärachsen (engl. Twin Axes). Wir demonstrieren ihre Anwendung im nächsten Beispiel. Zunächst dividieren wir die Spalte Fläche durch 10000, um die ursprünglichen Werte wiederherzustellen:

# prog4web
city_frame["Fläche"] /= 10000

Um die Darstellung mit Sekundärachsen zu erreichen, benötigen wir subplots aus dem Modul matplotlib und die Funktion "twinx":

# prog4web
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
fig.suptitle("Städtestatistik")
ax.set_ylabel("Bevölkerung")
ax.set_xlabel("Städte")

ax2 = ax.twinx()
ax2.set_ylabel("Fläche")

line1 = city_frame["Bevölkerung"].plot(ax=ax, 
                                       style="b-",
                                       xticks=range(len(city_frame.index)),
                                       use_index=True, 
                                       rot=60)

line2 = city_frame["Fläche"].plot(ax=ax2, 
                                  style="g-")


ax.legend(["Bevölkerung"], loc=2)
ax2.legend(loc=1)


plt.show()
No description has been provided for this image
# prog4book
import matplotlib.pyplot as plt

ax = kreta_df['Maximal'].plot(xticks=range(len(kreta_df.index)),
                              figsize=(3.5, 3.5),
                              use_index=True, 
                              title='Jahresklima auf Kreta',
                              rot=60)

kreta_df['Durchschnitt'].plot(ax=ax,
                              xticks=range(len(kreta_df.index)),
                              use_index=True, 
                              rot=60)
kreta_df['Minimal'].plot(ax=ax,
                         xticks=range(len(kreta_df.index)),
                         use_index=True, 
                         rot=60)

ax2 = ax.twinx()

kreta_df['Niederschlag'].plot(ax=ax2, 
                              style="r-")


ax.set_ylabel('Temperatur')
ax.set_xlabel('Monate')
ax2.set_ylabel('Niederschlagsmenge in mm')

ax.legend(['Max', 'Durch', 'Min'], loc=2)
ax2.legend(loc=1)


plt.show()
No description has been provided for this image

Wir können Sekundärachsen auch direkt in Pandas ohne Zuhilfenahme von Sublṕlots erzeugen, wie wir im Code des folgenden Programmes sehen:

# prog4web
import matplotlib.pyplot as plt

ax1 = city_frame["Bevölkerung"].plot(style="b-",
                                     xticks=range(len(city_frame.index)),
                                     use_index=True, 
                                     rot=60)
ax2 = ax1.twinx()
#ax2.spines['right'].set_position(('axes', 1.0))
city_frame["Fläche"].plot(ax=ax2,
                          style="g-")



ax1.legend(loc=(.7,.9), frameon = False)
ax2.legend( loc=(.7, .85), frameon = False)
Ausgabe:
<matplotlib.legend.Legend at 0x74254c28f890>
No description has been provided for this image

Mehrere Y-Achsen

Es lassen sich noch weitere Achsen hinzufügen.

Wir fügen eine weitere Achse zum city_frame hinzu, indem wir eine neue Spalte mit der Bevölkerungsdichte erstellen, d.h. die Anzahl der Menschen pro Quadratkilometer:

# prog4book

import matplotlib.pyplot as plt

sonnenstunden = [5, 4, 8, 9, 10, 12, 12, 12, 9, 8, 9, 5]
kreta_dict = {"Maximal": max_temperatur, 
              "Durchschnitt":durchschnitts_temperatur, 
              "Minimal": min_temperatur, 
              "Niederschlag": niederschlag_mm,
              "Sonnenstunden": sonnenstunden}
kreta_df = pd.DataFrame(kreta_dict, index=monate)

ax = kreta_df['Durchschnitt'].plot(xticks=range(len(kreta_df.index)), 
                                   figsize=(5, 3),
                                   style="g-",
                                   use_index=True, 
                                   title='Jahresklima auf Kreta',
                                   rot=60)


ax_regen, ax_sonne = ax.twinx(), ax.twinx()

kreta_df['Niederschlag'].plot(ax=ax_regen, 
                              style="r-")

kreta_df['Sonnenstunden'].plot(ax=ax_sonne, 
                               style="b-")

ax.set_ylabel('Temperatur')
ax.set_xlabel('Monate')
ax_regen.set_ylabel('Niederschlagsmenge in mm')
ax_sonne.set_ylabel('Sonnenstunden pro Tag')

ax_regen.spines['right'].set_position(('axes', 1.0))
ax_sonne.spines['right'].set_position(('axes', 1.15))

ax.legend(['Temperatur'], 
          loc='upper left', 
          bbox_to_anchor=(0.0, 1.0), 
          frameon=False)
ax_regen.legend(loc='upper left', 
                bbox_to_anchor=(0.0, 0.94), 
                frameon=False)
ax_sonne.legend(loc='upper left', 
                bbox_to_anchor=(0.0, 0.88),
                frameon=False)

#help(ax_sonne.legend)

#bbox_to_anchor=(1.5, 1)

plt.show()
No description has been provided for this image
# prog4web
city_frame["Dichte"] = city_frame["Bevölkerung"] / city_frame["Fläche"]

print(city_frame.head(3))
        Bevölkerung   Fläche       Dichte
London      8615246  1572.00  5480.436387
Berlin      3562166   891.85  3994.131300
Madrid      3165235   605.77  5225.143206

Damit gibt es drei Spalten zu zeichnen. Für diesen Zweck erstellen wir drei Achsen um die Werte darzustellen:

# prog4web
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
fig.suptitle("Städtestatistik")
ax.set_ylabel("Bevölkerung")
ax.set_xlabel("Städte")

ax_area, ax_density = ax.twinx(), ax.twinx() 
ax_area.set_ylabel("Fläche")
ax_density.set_ylabel("Dichte")

rspine = ax_density.spines['right']
rspine.set_position(('axes', 1.25))
ax_density.set_frame_on(True)
ax_density.patch.set_visible(False)
fig.subplots_adjust(right=0.75)

city_frame["Bevölkerung"].plot(ax=ax, 
                               style="b-",
                               xticks=range(len(city_frame.index)),
                               use_index=True, 
                               rot=60)

city_frame["Fläche"].plot(ax=ax_area, 
                         style="g-")

city_frame["Dichte"].plot(ax=ax_density, 
                          style="r-")

plt.show()
No description has been provided for this image

Ein komplexeres Beispiel

Wir nutzen das zuvor erlangte Wissen im nächsten Beispiel. Wir verwenden dazu eine Datei mit Besucherstatistiken der Webseite python-course.eu. Der Inhalt der Datei sieht folgendermaßen aus:

Month Year 'Unique visitors' 'Number of visits' Pages Hits Bandwidth Unit
Jun 2010 11 13 42 290 2.63 MB
Jul 2010 27 39 232 939 9.42 MB
Aug 2010 75 87 207 1,096 17.37 MB

...

Aug 2018 407,512 642,542 1,223,319 7,829,987 472.37 GB
Sep 2018 463,937 703,327 1,187,224 8,468,723 514.46 GB
Oct 2018 537,343 826,290 1,403,176 10,013,025 620.55 GB
Nov 2018 514,072 781,335 1,295,594 9,487,834 642.16 GB
Dec 2018 464,763 682,741 1,209,298 8,348,946 544.44 GB

Das Einlesen dieser Datei können wir mittels read_csv bewerkstelligen. Die Daten sind durch Whitespaces getrennt. Damit auch eine Folge von Whitespaces als ein Delimiter erkannt wird, benutzen wir einen regulären Ausdruck, d.h. r'\s+'. Die Tausenderstellen sind mit "," getrennt.

import pandas as pd

data_path = 'data1/'
fname = 'python_course_monthly_history.txt'
webstats = pd.read_csv(data_path + fname, 
                       quotechar='"',
                       thousands=',',
                       delimiter=r'\s+')
# umbenennen der Spaltennamen:
webstats.columns = ['Month', 'Year', 'Visitors', 'Visits', 
                    'Pages', 'Hits', 'Bandwidth', 'Unit']

webstats.head()
Ausgabe:
Month Year Visitors Visits Pages Hits Bandwidth Unit
0 Jun 2010 11 13 42 290 2.63 MB
1 Jul 2010 27 39 232 939 9.42 MB
2 Aug 2010 75 87 207 1096 17.37 MB
3 Sep 2010 171 221 480 2373 39.63 MB
4 Oct 2010 238 301 552 2872 52.13 MB

Wir erkennen, dass die Angaben für die Bandbreite (Bandwidth) nicht in einer festen Einheit angegeben sind, sondern von der letzten Spalte abhängen. Sie können in Bytes, Megabytes oder in Gigabytes sein. Die Funktion unit_convert wandelt ein Tupel, bestehend aus einem Wert und einer Einheit, in einen Bytewert um. Wir wenden diese Funktion nun auf die beiden letzten Spalten an. Der Parameter axis muss auf 1 gesetzt sein, damit die Funktion jeweils auf einen Wert und eine Einheit angewendet wird:

def unit_convert(x):
    value, unit = x
    if unit == 'MB':
        value *= 1024
    elif unit == 'GB':
        value *= 1048576 # i.e. 1024 **2
    return value

cols = ['Bandwidth', 'Unit']
bandwidth = webstats[cols].apply(unit_convert, 
                                 axis=1)

Als Nächstes löschen wir die 'unit'-Spalte und ersetzen die 'Bandwidth'-Spalte mit den neu berechneten Werten bandwidth. Außerdem ersetzen wir die Monatsangaben durch einen neuen Stringwert, bestehend aus Monat und Jahr. Die Spalte Year löschen wir dann.

del webstats['Unit']
webstats['Bandwidth'] = bandwidth

def concat(x):
    """concatenates month and year"""
    return x[0] + " " + str(x[1])

month_year = webstats[['Month', 'Year']]
month_year = month_year.apply(concat, 
                              axis=1)
webstats['Month'] = month_year
del webstats['Year']

webstats.set_index('Month', inplace=True)
del webstats['Bandwidth']


webstats[:10]
/tmp/ipykernel_55009/2292131772.py:6: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  return x[0] + " " + str(x[1])
Ausgabe:
Visitors Visits Pages Hits
Month
Jun 2010 11 13 42 290
Jul 2010 27 39 232 939
Aug 2010 75 87 207 1096
Sep 2010 171 221 480 2373
Oct 2010 238 301 552 2872
Nov 2010 353 455 912 5086
Dec 2010 366 423 944 4884
Jan 2011 911 1111 2321 11442
Feb 2011 1488 1807 4139 22291
Mar 2011 2128 2762 6009 32407

Nun sind wir bereit für den Plot des DataFrames:

xticks = range(1, len(webstats.index), 4)
webstats[['Visitors', 'Visits']].plot(use_index=True, 
                                      rot=90,
                                      xticks=xticks)

plt.plot()
Ausgabe:
[]
No description has been provided for this image

Wir berechnen nun die durchschnittliche Anzahl der Besuche pro Besucher.

ratio = pd.Series(webstats["Visits"] / webstats["Visitors"],
                  index=webstats.index)
ratio.plot(use_index=True, 
           xticks=range(1, len(ratio.index), 4),
           rot=90)
plt.show()
No description has been provided for this image

Spalten mit Zeichenketten (Strings) in Floats wandeln

Im Verzeichnis data1 haben wir die Datei

tiobe_programming_language_usage_nov2018.txt

mit einem Nutzungs-Ranking von Programmiersprachen. Die Daten wurden gesammelt und aufbereitet von TIOBE im November 2018.

Die Datei hat folgenden Inhalt:

Position    "Language"          Percentage
1           Java                16.748%
2           C                   14.396%
3           C++                  8.282%
4           Python               7.683%
5           "Visual Basic .NET"  6.490%
6           C#                   3.952%

Die Prozent-Spalte enthält Strings mit dem Prozent-Zeichen. Das Zeichen können wir nutzen (oder loswerden), indem wir die Funktion read_csv verwenden. Alles, was wir dafür tun müssen, ist, eine Konverter-Funktion zu definieren. Diese Konverter-Funktion übergeben wir dann an read_csv mit dem Parameter converters.

import pandas as pd
def strip_percentage_sign(x):
    return float(x.strip('%'))
data_path = "data1/"
fname = "tiobe_programming_language_usage_jun2025.csv"
progs = pd.read_csv(
    data_path + fname,
    quotechar="'",
    index_col=2,
    converters={'Ratings': strip_percentage_sign,
                'Change': strip_percentage_sign},
    delimiter=r",")

print(progs)
                    Jun 2024   Jun 2025   Ratings  Change
Programmiersprache                                       
Python                      1          1    25.87   10.48
C++                         2          2    10.68    0.65
C                           3          3     9.47    0.24
Java                        4          4     8.84    0.44
C#                          5          5     4.69   -1.96
JavaScript                  6          6     3.21   -0.11
Go                          7          7     2.28    0.35
Visual Basic                8          9     2.20    0.54
Object Pascal               9         11     2.15    0.62
Fortran                    10         10     1.86    0.33
Ada                        11         25     1.70    0.91
SQL                        12          8     1.55   -0.21
Perl                       13         27     1.47    0.77
R                          14         21     1.39    0.43
PHP                        15         15     1.25    0.03
Scratch                    16         16     1.19    0.02
MATLAB                     17         14     1.13   -0.13
Rust                       18         17     0.97   -0.20
Assembly language          19         13     0.91   -0.35
COBOL                      20         20     0.89   -0.08
progs['Ratings'].plot(kind="bar",
                      use_index=True, 
                      rot=90,
                      color='skyblue')

plt.ylabel("Prozent")
plt.title("TIOBE-Ranking Juni 2025")
plt.tight_layout()
No description has been provided for this image
# Rating 2024 berechnen
progs["Ratings2024"] = progs["Ratings"] - progs["Change"]
progs
Ausgabe:
Jun 2024 Jun 2025 Ratings Change Rating2024 Ratings2024
Programmiersprache
Python 1 1 25.87 10.48 15.39 15.39
C++ 2 2 10.68 0.65 10.03 10.03
C 3 3 9.47 0.24 9.23 9.23
Java 4 4 8.84 0.44 8.40 8.40
C# 5 5 4.69 -1.96 6.65 6.65
JavaScript 6 6 3.21 -0.11 3.32 3.32
Go 7 7 2.28 0.35 1.93 1.93
Visual Basic 8 9 2.20 0.54 1.66 1.66
Object Pascal 9 11 2.15 0.62 1.53 1.53
Fortran 10 10 1.86 0.33 1.53 1.53
Ada 11 25 1.70 0.91 0.79 0.79
SQL 12 8 1.55 -0.21 1.76 1.76
Perl 13 27 1.47 0.77 0.70 0.70
R 14 21 1.39 0.43 0.96 0.96
PHP 15 15 1.25 0.03 1.22 1.22
Scratch 16 16 1.19 0.02 1.17 1.17
MATLAB 17 14 1.13 -0.13 1.26 1.26
Rust 18 17 0.97 -0.20 1.17 1.17
Assembly language 19 13 0.91 -0.35 1.26 1.26
COBOL 20 20 0.89 -0.08 0.97 0.97
# Neue DataFrame mit beiden Jahren
ratings_df = progs[["Ratings2024", "Ratings"]].copy()
ratings_df.columns = ["2024", "2025"]

# Optional: sortieren nach 2025
ratings_df = ratings_df.sort_values("2025", ascending=False)

# Balkendiagramm
ax = ratings_df.plot(kind="bar",
                     rot=45,
                     color=["lightgray", "steelblue"],
                     figsize=(10, 5))

ax.set_ylabel("Prozent")
ax.set_title("TIOBE-Rankings 2024 vs. 2025")
fig = ax.get_figure()
fig.tight_layout()
No description has been provided for this image

Balkendiagramme in Pandas

Balkendiagramme mit Pandas zu erstellen, ist ebenso einfach wie Liniendiagramme. Dazu fügen wir den Schlüsselwort-Parameter kind zu plot-Methode hinzu und setzen den Wert auf bar.

Ein einfaches Beispiel

import pandas as pd

data = [100, 120, 140, 180, 200, 210, 214]
s = pd.Series(data, index=range(len(data)))

s.plot(kind="bar", rot=0)
plt.plot()
Ausgabe:
[]
No description has been provided for this image

Balken-Grafik für die Programmiersprachennutzung

Wir gehen zurück zum Beispiel des Programmiersprachen-Rankings. Jetzt generieren wir eine Balkengrafik der sechs meistverwendeten Programmiersprachen:

progs[:6].plot(kind="bar")
Ausgabe:
<matplotlib.axes._subplots.AxesSubplot at 0x7f7339668748>
No description has been provided for this image

Nun die Balkendiagramme mit allen Programmiersprachen:

progs.plot(kind="bar")
Ausgabe:
<matplotlib.axes._subplots.AxesSubplot at 0x7f73397f5668>
No description has been provided for this image

Farbgebung einer Balken-Grafik

Es ist möglich, die Balken individuell zu färben, indem eine Liste dem Schlüsselwort-Parameter color zugewiesen wird:

my_colors = ['b', 'r', 'c', 'y', 'g', 'm']
progs[:6].plot(kind="bar",
               color=my_colors)
Ausgabe:
<Axes: xlabel='Programmiersprache'>
No description has been provided for this image

Kuchen-Diagramme in Pandas

Ein einfaches Beispiel

import pandas as pd

fruits = ['apples', 'pears', 'cherries', 'bananas']
series = pd.Series([20, 30, 40, 10], 
                   index=fruits, 
                   name='Fruits')

series.plot.pie(figsize=(6, 6))
Ausgabe:
<matplotlib.axes._subplots.AxesSubplot at 0x7f7338e9e588>
No description has been provided for this image

Obiges Kreisdiagramm lässt einen an einen Kuchen denken, und wie bei einem Kuchen, kann man einzelne "Stücke" herausziehen, was sich mit dem Parameter explode bewerkstelligen lässt. Diesem kann man eine Array-ähnliche Struktur, wie z.B. ein Tupel oder Liste, übergeben, die den Abstand vom Kreismittelpunkt beschreibt. Die Default-Werte sind 0, d.h. die "Kuchenstücke" sind nicht herausgezogen:

fruits = ['apples', 'pears', 'cherries', 'bananas']

series = pd.Series([20, 30, 40, 10], 
                   index=fruits, 
                   name='Fruits')
explode = [0, 0.10, 0.40, 0.5]
series.plot.pie(figsize=(6, 6),
                explode=explode)
Ausgabe:
<matplotlib.axes._subplots.AxesSubplot at 0x7f7338e5efd0>
No description has been provided for this image

Wir generieren die vorherige Balken-Grafik (Programmiersprachen) nun als Kuchendiagramm:

import matplotlib.pyplot as plt

my_colors = ['b', 'r', 'c', 'y', 'g', 'm']
progs.plot.pie(subplots=True,
               legend=False)
Ausgabe:
array([<matplotlib.axes._subplots.AxesSubplot object at 0x7f7338e1a9e8>],
      dtype=object)
No description has been provided for this image

Es ist nicht schön, dass das y-Label Percentage innerhalb der Grafik angezeigt wird. Wir entfernen die Bezeichnung mit der Funktion plt.ylabel.

import matplotlib.pyplot as plt

my_colors = ['b', 'r', 'c', 'y', 'g', 'm']
progs.plot.pie(subplots=True,
               legend=False)

plt.ylabel('')
Ausgabe:
Text(0, 0.5, '')
No description has been provided for this image

Alle Alternativen für den Parameter kind im Überblick:

  • line: Liniendiagramm (Default-Wert)
  • bar: Säulendiagramm
  • hist: Histogramm
  • box: Kastengrafik (engl. Box Plot)
  • kde: Kernel Density Estimation plot
  • density: wie kde
  • area: Flächendiagramm
  • pie: Kreisdiagramm