Wie kann ich separate Pandas DataFrames als Unterzeichnungen zeichnen?

128

Ich habe einige Pandas DataFrames, die dieselbe Werteskala verwenden, aber unterschiedliche Spalten und Indizes haben. Beim Aufrufen df.plot()erhalte ich separate Plotbilder. Was ich wirklich möchte, ist, dass sie alle in derselben Handlung wie Nebenhandlungen sind, aber ich finde leider keine Lösung dafür, wie und würde mich über Hilfe sehr freuen.

Jimmy C.
quelle

Antworten:

249

Sie können die Unterzeichnungen manuell mit matplotlib erstellen und dann die Datenrahmen mit dem axSchlüsselwort in einer bestimmten Unterzeichnung zeichnen . Zum Beispiel für 4 Nebenhandlungen (2x2):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)

df1.plot(ax=axes[0,0])
df2.plot(ax=axes[0,1])
...

Hier axesist ein Array, das die verschiedenen Unterplotachsen enthält, und Sie können nur durch Indizieren auf eines zugreifen axes.
Wenn Sie eine gemeinsame x-Achse wollen, dann können Sie zur Verfügung stellen sharex=Truezu plt.subplots.

Joris
quelle
33
Beachten Sie, dass ärgerlicherweise .subplots()je nach den Abmessungen des von Ihnen erstellten Arrays von Unterplots unterschiedliche Koordinatensysteme zurückgegeben werden. Wenn Sie also Unterzeichnungen zurückgeben, in denen nrows=2, ncols=1Sie beispielsweise die Achsen als axes[0]und indizieren müssen axes[1]. Siehe stackoverflow.com/a/21967899/1569221
canary_in_the_data_mine
3
@canary_in_the_data_mine Danke, das ist wirklich ärgerlich ... Ihr Kommentar gespeichert mir etwas Zeit :) konnte nicht herausfinden , warum ich immerIndexError: too many indices for array
snd
9
@canary_in_the_data_mine Das ist nur ärgerlich, wenn Standardargumente für .subplot()verwendet werden. Auf squeeze=FalseForce setzen .subplot(), um ndarrayin jedem Fall von Zeilen und Spalten immer ein zurückzugeben .
Martin
73

Sie können z.B. in der Dokumentation , die joris Antwort demonstriert. Auch aus der Dokumentation können Sie auch subplots=Trueund layout=(,)innerhalb der Pandas- plotFunktion einstellen :

df.plot(subplots=True, layout=(1,2))

Sie können auch fig.add_subplot()Subplot-Rasterparameter wie 221, 222, 223, 224 usw. verwenden, wie im Beitrag hier beschrieben . In diesem Ipython-Notizbuch sind schöne Beispiele für die Darstellung im Pandas- Datenrahmen zu sehen, einschließlich Unterzeichnungen .

sedeh
quelle
2
Obwohl die Antwort von joris für die allgemeine Verwendung von Matplotlib großartig ist, ist sie hervorragend für alle geeignet, die Pandas für eine schnelle Datenvisualisierung verwenden möchten. Es passt auch etwas besser zur Frage.
Little Bobby Tables
Beachten Sie, dass subplotsund layoutkwargs NUR mehrere Diagramme für einen einzelnen Datenrahmen generieren. Dies hängt mit der Frage von OP zusammen, mehrere Datenrahmen in einem einzigen Diagramm zu zeichnen, ist jedoch keine Lösung dafür.
Austin A
1
Dies ist die bessere Antwort für den reinen Pandas-Gebrauch. Dies erfordert kein direktes Importieren von matplotlib (obwohl dies normalerweise sowieso der Fall sein sollte) und keine Schleife für beliebige Formen (kann layout=(df.shape[1], 1)beispielsweise verwendet werden).
Anatoly Makarevich
20

Sie können den bekannten Matplotlib-Stil verwenden, der ein figureund aufruft subplot, aber Sie müssen lediglich die aktuelle Achse mit angeben plt.gca(). Ein Beispiel:

plt.figure(1)
plt.subplot(2,2,1)
df.A.plot() #no need to specify for first axis
plt.subplot(2,2,2)
df.B.plot(ax=plt.gca())
plt.subplot(2,2,3)
df.C.plot(ax=plt.gca())

etc...

Q-Mann
quelle
6

Mit matplotlib können Sie mehrere Unterzeichnungen mehrerer Pandas-Datenrahmen mit einem einfachen Trick zeichnen, indem Sie eine Liste aller Datenrahmen erstellen. Verwenden Sie dann die for-Schleife zum Zeichnen von Unterplots.

Arbeitscode:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# dataframe sample data
df1 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df2 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df3 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df4 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df5 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
df6 = pd.DataFrame(np.random.rand(10,2)*100, columns=['A', 'B'])
#define number of rows and columns for subplots
nrow=3
ncol=2
# make a list of all dataframes 
df_list = [df1 ,df2, df3, df4, df5, df6]
fig, axes = plt.subplots(nrow, ncol)
# plot counter
count=0
for r in range(nrow):
    for c in range(ncol):
        df_list[count].plot(ax=axes[r,c])
        count=+1

Geben Sie hier die Bildbeschreibung ein

Mit diesem Code können Sie Unterzeichnungen in jeder Konfiguration zeichnen. Sie müssen nur die Anzahl der Zeilen nrowund Spalten definieren ncol. Außerdem müssen Sie eine Liste der Datenrahmen erstellen, df_listdie Sie zeichnen möchten.

Dr. Arslan
quelle
2
count =+1count +=1
Achten
4

Sie können dies verwenden:

fig = plt.figure()
ax = fig.add_subplot(221)
plt.plot(x,y)

ax = fig.add_subplot(222)
plt.plot(x,z)
...

plt.show()
Joe
quelle
3

Möglicherweise müssen Sie Pandas überhaupt nicht verwenden. Hier ist ein Matplotlib-Diagramm der Katzenfrequenzen:

Geben Sie hier die Bildbeschreibung ein

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

f, axes = plt.subplots(2, 1)
for c, i in enumerate(axes):
  axes[c].plot(x, y)
  axes[c].set_title('cats')
plt.tight_layout()
duhaime
quelle
1

Aufbauend auf der obigen @ joris-Antwort können Sie die Referenz auch verwenden, wenn Sie bereits einen Verweis auf das Unterplot erstellt haben. Beispielsweise,

ax1 = plt.subplot2grid((50,100), (0, 0), colspan=20, rowspan=10)
...

df.plot.barh(ax=ax1, stacked=True)
DaveL17
quelle
0

So erstellen Sie mehrere Diagramme aus einem Wörterbuch von Datenrahmen mit langen (ordentlichen) Daten

  • Annahmen

    • Es gibt ein Wörterbuch mit mehreren Datenrahmen für aufgeräumte Daten
      • Erstellt durch Einlesen aus Dateien
      • Erstellt durch Trennen eines einzelnen Datenrahmens in mehrere Datenrahmen
    • Die Kategorien catkönnen sich überlappen, aber alle Datenrahmen enthalten möglicherweise nicht alle Werte voncat
    • hue='cat'
  • Da Datenrahmen durchlaufen werden, kann nicht garantiert werden, dass die Farben für jedes Diagramm gleich zugeordnet werden

    • Aus den eindeutigen 'cat'Werten für alle Datenrahmen muss eine benutzerdefinierte Farbkarte erstellt werden
    • Da die Farben gleich sind, platzieren Sie eine Legende neben den Plots anstelle einer Legende in jedem Plot

Importe und synthetische Daten

import pandas as pd
import numpy as np  # used for random data
import random  # used for random data
import matplotlib.pyplot as plt
from matplotlib.patches import Patch  # for custom legend
import seaborn as sns
import math import ceil  # determine correct number of subplot


# synthetic data
df_dict = dict()
for i in range(1, 7):
    np.random.seed(i)
    random.seed(i)
    data_length = 100
    data = {'cat': [random.choice(['A', 'B', 'C']) for _ in range(data_length)],
            'x': np.random.rand(data_length),
            'y': np.random.rand(data_length)}
    df_dict[i] = pd.DataFrame(data)


# display(df_dict[1].head())

  cat         x         y
0   A  0.417022  0.326645
1   C  0.720324  0.527058
2   A  0.000114  0.885942
3   B  0.302333  0.357270
4   A  0.146756  0.908535

Erstellen Sie Farbzuordnungen und Plots

# create color mapping based on all unique values of cat
unique_cat = {cat for v in df_dict.values() for cat in v.cat.unique()}  # get unique cats
colors = sns.color_palette('husl', n_colors=len(unique_cat))  # get a number of colors
cmap = dict(zip(unique_cat, colors))  # zip values to colors

# iterate through dictionary and plot
col_nums = 3  # how many plots per row
row_nums = math.ceil(len(df_dict) / col_nums)  # how many rows of plots
plt.figure(figsize=(10, 5))  # change the figure size as needed
for i, (k, v) in enumerate(df_dict.items(), 1):
    plt.subplot(row_nums, col_nums, i)  # create subplots
    p = sns.scatterplot(data=v, x='x', y='y', hue='cat', palette=cmap)
    p.legend_.remove()  # remove the individual plot legends
    plt.title(f'DataFrame: {k}')

plt.tight_layout()
# create legend from cmap
patches = [Patch(color=v, label=k) for k, v in cmap.items()]
# place legend outside of plot; change the right bbox value to move the legend up or down
plt.legend(handles=patches, bbox_to_anchor=(1.06, 1.2), loc='center left', borderaxespad=0)
plt.show()

Geben Sie hier die Bildbeschreibung ein

Trenton McKinney
quelle