Cara memplot kolom dari kerangka data, sebagai subplot
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
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 () .
- 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 untukmatplotlib, 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.
Datetidak ditentukan untukx = Datey2 = Notes:Notestidak ditentukan.linebukanlahpltmetode dan menyebabkanAttributeError; harusplt.ploty1 - y4adalah DataFrames, tetapi diteruskan ke metode plot untuk sumbu y, yang menyebabkanTypeError: unhashable type: 'numpy.ndarray'; satu kolom harus dilewati sebagaiy..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()