Cara memplot kolom dari kerangka data, sebagai subplot

Oct 10 2020

Apa yang saya lakukan salah di sini? Saya ingin membuat kerangka data baru dari dfdan menggunakan Tanggal sebagai sumbu x dalam bagan garis untuk setiap kerangka data yang baru dibuat (Emins, FTSE, Stoxx, dan Nikkei).

Saya memiliki dataframe dfyang saya buat dari data.xlsx dan terlihat seperti ini:

    Dates         ES1     Z 1     VG1     NK1
0   2005-01-04  -0.0126  0.0077 -0.0030  0.0052
1   2005-01-05  -0.0065 -0.0057  0.0007 -0.0095
2   2005-01-06   0.0042  0.0017  0.0051  0.0044
3   2005-01-07  -0.0017  0.0061  0.0010 -0.0009
4   2005-01-11  -0.0065 -0.0040 -0.0147  0.0070
3670    2020-09-16  -0.0046 -0.0065 -0.0003 -0.0009
3671    2020-09-17  -0.0083 -0.0034 -0.0039 -0.0086
3672    2020-09-18  -0.0024 -0.0009 -0.0009  0.0052
3673    2020-09-23  -0.0206  0.0102  0.0022 -0.0013
3674    2020-09-24  0.0021  -0.0136 -0.0073 -0.0116

Dari dfsaya membuat 4 dataframe baru bernama Eminis, FTSE, Stoxx dan Nikkei.

Terima kasih atas bantuan Anda!!!!

    import numpy as np
    import matplotlib.pyplot as plt
    plt.style.use('classic')
    
    df = pd.read_excel('data.xlsx')
    df = df.rename(columns={'Dates':'Date','ES1': 'Eminis', 'Z 1': 'FTSE','VG1': 'Stoxx','NK1': 'Nikkei','TY1': 'Notes','G 1': 'Gilts', 'RX1': 'Bunds','JB1': 'JGBS','CL1': 'Oil','HG1': 'Copper','S 1': 'Soybeans','GC1': 'Gold','WILLTIPS': 'TIPS'})
    headers = df.columns
    Eminis = df[['Date','Eminis']]
    FTSE = df[['Date','FTSE']]
    Stoxx = df[['Date','Stoxx']]
    Nikkei = df[['Date','Nikkei']]
    
    # create multiple plots via plt.subplots(rows,columns)
    fig, axes = plt.subplots(2,2, figsize=(20,15))
    x = Date
    y1 = Eminis
    y2 = Notes
    y3 = Stoxx
    y4 = Nikkei
    
    # one plot on each subplot
    axes[0][0].line(x,y1)
    axes[0][1].line(x,y2)
    axes[1][0].line(x,y3)
    axes[1][1].line(x,y4)
    
    plt.legends()
    plt.show()

Jawaban

1 Valdi_Bo Oct 11 2020 at 04:58

Solusi elegannya adalah:

  • Tetapkan kolom Tanggal di DataFrame Anda sebagai indeks.
  • Buat gambar dengan jumlah subplot yang diperlukan (dalam kasus Anda 4), panggil plt.subplots .
  • Gambar plot dari DataFrame Anda, dengan meneruskan:
    • kapak - yang kapak hasil dari subplot (di sini adalah berbagai dari Axes objek, tidak satu Axes ),
    • subplot = Benar - untuk menggambar setiap kolom dalam subplot terpisah.

Kode untuk melakukannya adalah:

fig, a = plt.subplots(2, 2, figsize=(12, 6), tight_layout=True)
df.plot(ax=a, subplots=True, rot=60);

Untuk menguji kode di atas saya membuat DataFrame berikut:

np.random.seed(1)
ind = pd.date_range('2005-01-01', '2006-12-31', freq='7D')
df = pd.DataFrame(np.random.rand(ind.size, 4),
    index=ind, columns=['ES1', 'Z 1', 'VG1', 'NK1'])

dan mendapatkan gambar berikut:

Karena data pengujian saya acak, saya berasumsi frekuensi "7 hari", agar gambar tidak terlalu "berantakan". Dalam kasus data asli Anda, pertimbangkan misalnya pengambilan sampel kembali dengan misalnya juga frekuensi '7D' dan fungsi agregasi mean () .

1 TrentonMcKinney Oct 11 2020 at 01:06
  • Saya pikir pilihan yang lebih ringkas bukanlah membuat banyak kerangka data, yang menciptakan pekerjaan yang tidak perlu, dan kompleksitas.
  • Merencanakan data adalah tentang membentuk kerangka data untuk API plot
  • Dalam hal ini, opsi yang lebih baik adalah mengonversi kerangka data ke format panjang (rapi), dari format lebar, menggunakan .stack.
    • Ini menempatkan semua label dalam satu kolom, dan nilai di kolom lain
  • Gunakan seaborn.relplot, yang dapat membuat FacetGriddari dataframe dalam format yang panjang.
    • seabornadalah API tingkat tinggi untuk matplotlib, dan membuat pembuatan plot menjadi lebih mudah.
  • Jika kerangka data berisi banyak saham, tetapi hanya sedikit yang akan diplot, mereka dapat dipilih dengan pengindeksan Boolean
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# import data from excel, or setup test dataframe
data = {'Dates': ['2005-01-04', '2005-01-05', '2005-01-06', '2005-01-07', '2005-01-11', '2020-09-16', '2020-09-17', '2020-09-18', '2020-09-23', '2020-09-24'],
        'ES1': [-0.0126, -0.0065, 0.0042, -0.0017, -0.0065, -0.0046, -0.0083, -0.0024, -0.0206, 0.0021],
        'Z 1': [0.0077, -0.0057, 0.0017, 0.0061, -0.004, -0.0065, -0.0034, -0.0009, 0.0102, -0.0136],
        'VG1': [-0.003, 0.0007, 0.0051, 0.001, -0.0147, -0.0003, -0.0039, -0.0009, 0.0022, -0.0073],
        'NK1': [0.0052, -0.0095, 0.0044, -0.0009, 0.007, -0.0009, -0.0086, 0.0052, -0.0013, -0.0116]}

df = pd.DataFrame(data)

# rename columns
df = df.rename(columns={'Dates':'Date','ES1': 'Eminis', 'Z 1': 'FTSE','VG1': 'Stoxx','NK1': 'Nikkei'})

# set Date to a datetime
df.Date = pd.to_datetime(df.Date)

# set Date as the index
df.set_index('Date', inplace=True)

# stack the dataframe
dfs = df.stack().reset_index().rename(columns={'level_1': 'Stock', 0: 'val'})

# to select only a subset of values from Stock, to plot, select them with Boolean indexing
df_select = dfs[dfs.Stock.isin(['Eminis', 'FTSE', 'Stoxx', 'Nikkei'])]`

# df_select.head()
        Date   Stock     val
0 2005-01-04  Eminis -0.0126
1 2005-01-04    FTSE  0.0077
2 2005-01-04   Stoxx -0.0030
3 2005-01-04  Nikkei  0.0052
4 2005-01-05  Eminis -0.0065

# plot
sns.relplot(data=df_select, x='Date', y='val', col='Stock', col_wrap=2, kind='line')

Apa yang saya lakukan salah di sini?

  • Implementasi saat ini tidak efisien, memiliki sejumlah panggilan metode yang salah, dan variabel yang tidak ditentukan.
    • Date tidak ditentukan untuk x = Date
    • y2 = Notes: Notestidak ditentukan
    • .linebukanlah pltmetode dan menyebabkan AttributeError; harusplt.plot
    • y1 - y4adalah DataFrames, tetapi diteruskan ke metode plot untuk sumbu y, yang menyebabkan TypeError: unhashable type: 'numpy.ndarray'; satu kolom harus dilewati sebagai y.
    • .legendsbukanlah sebuah metode; nya.legend
      • Legenda harus ditampilkan untuk setiap subplot, jika diinginkan.
Eminis = df[['Date','Eminis']]
FTSE = df[['Date','FTSE']]
Stoxx = df[['Date','Stoxx']]
Nikkei = df[['Date','Nikkei']]

# create multiple plots via plt.subplots(rows,columns)
fig, axes = plt.subplots(2,2, figsize=(20,15))
x = df.Date
y1 = Eminis.Eminis
y2 = FTSE.FTSE
y3 = Stoxx.Stoxx
y4 = Nikkei.Nikkei

# one plot on each subplot
axes[0][0].plot(x,y1, label='Eminis')
axes[0][0].legend()
axes[0][1].plot(x,y2, label='FTSE')
axes[0][1].legend()
axes[1][0].plot(x,y3, label='Stoxx')
axes[1][0].legend()
axes[1][1].plot(x,y4, label='Nikkei')
axes[1][1].legend()

plt.show()