Bagaimana cara memplot Pandas DataFrames yang terpisah sebagai subplot?

129

Saya memiliki beberapa Pandas DataFrames yang berbagi skala nilai yang sama, tetapi memiliki kolom dan indeks yang berbeda. Saat memohon df.plot(), saya mendapatkan gambar plot terpisah. apa yang sebenarnya saya inginkan adalah memiliki semuanya dalam plot yang sama dengan subplot, tetapi sayangnya saya gagal menemukan solusi tentang bagaimana dan akan sangat menghargai beberapa bantuan.

Jimmy C.
sumber

Jawaban:

252

Anda dapat membuat subplot secara manual dengan matplotlib, lalu memplot kerangka data pada subplot tertentu menggunakan axkata kunci. Misalnya untuk 4 subplot (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])
...

Berikut axesadalah larik yang menampung sumbu subplot yang berbeda, dan Anda dapat mengaksesnya hanya dengan mengindeks axes.
Jika Anda ingin bersama sumbu x, maka Anda dapat memberikan sharex=Trueke plt.subplots.

joris
sumber
33
Perhatikan bahwa, secara menjengkelkan, .subplots()mengembalikan sistem koordinat yang berbeda tergantung pada dimensi larik subplot yang Anda buat. Jadi jika Anda mengembalikan subplot di mana, katakanlah nrows=2, ncols=1, Anda harus mengindeks sumbu sebagai axes[0]dan axes[1]. Lihat stackoverflow.com/a/21967899/1569221
canary_in_the_data_mine
3
@canary_in_the_data_mine Terima kasih, itu benar-benar menjengkelkan ... komentar Anda menyelamatkan saya beberapa waktu :) tidak tahu mengapa saya mendapatkanIndexError: too many indices for array
snd
9
@canary_in_the_data_mine Itu hanya mengganggu jika argumen default untuk .subplot()digunakan. Setel squeeze=Falseke memaksa .subplot()untuk selalu mengembalikan ndarraydalam hal apa pun baris dan kolom.
Martin
73

Anda dapat melihat mis. dalam dokumentasi yang mendemonstrasikan jawaban joris. Juga dari dokumentasinya, Anda juga bisa mengatur subplots=Truedan layout=(,)di dalam plotfungsi pandas :

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

Anda juga bisa menggunakan fig.add_subplot()yang mengambil parameter grid subplot seperti 221, 222, 223, 224, dll seperti yang dijelaskan dalam posting di sini . Contoh plot yang bagus pada bingkai data panda, termasuk subplot, dapat dilihat di notebook ipython ini .

sedeh
sumber
2
meskipun jawaban joris bagus untuk penggunaan matplotlib umum, ini sangat bagus untuk siapa saja yang ingin menggunakan panda untuk visualisasi data yang cepat. Ini juga sesuai dengan pertanyaan yang sedikit lebih baik.
Little Bobby Tables
Perlu diingat bahwa subplotsdan layoutkwargs akan menghasilkan banyak plot HANYA untuk satu kerangka data. Ini terkait dengan, tetapi bukan solusi untuk pertanyaan OP untuk memplot beberapa kerangka data ke dalam satu plot.
Austin A
1
Ini adalah jawaban yang lebih baik untuk penggunaan Panda murni. Ini tidak memerlukan pengimporan matplotlib secara langsung (meskipun biasanya Anda harus melakukannya) dan tidak memerlukan pengulangan untuk bentuk arbitrer (dapat digunakan layout=(df.shape[1], 1), misalnya).
Anatoly Makarevich
20

Anda dapat menggunakan gaya Matplotlib yang sudah dikenal dengan memanggil figuredan subplot, tetapi Anda hanya perlu menentukan sumbu saat ini menggunakan plt.gca(). Sebuah contoh:

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())

dll ...

Q-man
sumber
7

Anda dapat memplot beberapa subplot dari beberapa bingkai data panda menggunakan matplotlib dengan trik sederhana membuat daftar semua bingkai data. Kemudian gunakan perulangan for untuk memplot subplot.

Kode kerja:

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

masukkan deskripsi gambar di sini

Dengan menggunakan kode ini, Anda dapat memplot subplot dalam konfigurasi apa pun. Anda hanya perlu menentukan jumlah baris nrowdan jumlah kolom ncol. Juga, Anda perlu membuat daftar bingkai data df_listyang ingin Anda plot.

Dr Arslan
sumber
2
perhatikan kesalahan ketik di baris terakhir: ini tidak count =+1tetapicount +=1
PEBKAC
4

Anda dapat menggunakan ini:

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

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

plt.show()
Joe
sumber
3

Anda mungkin tidak perlu menggunakan Panda sama sekali. Berikut plot matplotlib frekuensi kucing:

masukkan deskripsi gambar di sini

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
sumber
1

Berdasarkan tanggapan @joris di atas, jika Anda telah membuat referensi ke subplot, Anda juga dapat menggunakan referensi tersebut. Sebagai contoh,

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

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

Cara membuat beberapa plot dari kamus dataframe dengan data yang panjang (rapi)

  • Asumsi

    • Ada kamus beberapa kerangka data dari data yang rapi
      • Dibuat dengan membaca dari file
      • Dibuat dengan memisahkan satu kerangka data menjadi beberapa kerangka data
    • Kategori,, catmungkin tumpang tindih, tetapi semua kerangka data mungkin tidak berisi semua nilaicat
    • hue='cat'
  • Karena bingkai data sedang diiterasi, tidak ada jaminan bahwa warna akan dipetakan sama untuk setiap plot

    • Peta warna khusus perlu dibuat dari nilai unik 'cat'untuk semua kerangka data
    • Karena warnanya akan sama, letakkan satu legenda di sisi plot, bukan legenda di setiap plot

Impor dan data sintetis

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

Buat pemetaan dan plot warna

# 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()

masukkan deskripsi gambar di sini

Trenton McKinney
sumber