2017-04-25 58 views
0

我的目標是繪製類似於以下link的頂部圖的東西。熊貓三維圖的多個數據幀

我有幾個txt文件,每個文件對應不同的示例。 目前,我已經加載大熊貓dataframes我的數據(雖然我不知道,如果我加載numpy的陣列,它可能是更容易):

sample4.head() 
Out[61]: 
      20  40  60  80  100 
x             
1.10 1.09734 1.25772 1.41810 1.57847 1.73885 
1.11 1.06237 1.21307 1.36378 1.51448 1.66518 
1.12 1.02176 1.16346 1.30516 1.44686 1.58856 
1.13 0.97769 1.11097 1.24426 1.37754 1.51083 
1.14 0.93162 1.05702 1.18241 1.30781 1.43321 

test5.head() 
Out[62]: 
      20  40  60  80  100 
x             
1.10 1.12427 1.31545 1.50663 1.69781 1.88899 
1.11 1.06327 1.24045 1.41763 1.59482 1.77200 
1.12 0.99875 1.16302 1.32730 1.49158 1.65585 
1.13 0.93276 1.08509 1.23742 1.38975 1.54208 
1.14 0.86668 1.00792 1.14916 1.29040 1.43164 

test6.head() 
Out[63]: 
      20  40  60  80  100 
x             
1.10 1.08463 1.30038 1.51612 1.73187 1.94761 
1.11 0.99905 1.19626 1.39346 1.59067 1.78788 
1.12 0.91255 1.09283 1.27310 1.45337 1.63365 
1.13 0.82706 0.99181 1.15656 1.32131 1.48605 
1.14 0.74381 0.89429 1.04477 1.19525 1.34572 

如可以看出,所有樣品都有一個列。下面的方法也適用於單個樣品,給人一種簡單的2D情節:

sample4.plot() 

但我的想法是畫出我沿y軸都dataframes,即y軸應該是每個個體樣品的我在像上面的例子那樣的3d圖中,但我不知道如何「堆疊」數據框並使用第三軸繪製它們。

任何幫助,將不勝感激。

在此先感謝。

回答

2

以下是一種方法,使用meltAxes3D

首先,生成由OP提供的樣本數據:

import pandas as pd 
from matplotlib import pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 

sample4_z = [1.09734, 1.25772, 1.4181 , 1.57847, 1.73885, 1.06237, 
      1.21307, 1.36378, 1.51448, 1.66518, 1.02176, 1.16346, 
      1.30516, 1.44686, 1.58856, 0.97769, 1.11097, 1.24426, 
      1.37754, 1.51083, 0.93162, 1.05702, 1.18241, 1.30781, 
      1.43321] 

test5_z = [1.12427, 1.31545, 1.50663, 1.69781, 1.88899, 1.06327, 
      1.24045, 1.41763, 1.59482, 1.772 , 0.99875, 1.16302, 
      1.3273 , 1.49158, 1.65585, 0.93276, 1.08509, 1.23742, 
      1.38975, 1.54208, 0.86668, 1.00792, 1.14916, 1.2904 , 
      1.43164] 

test6_z = [1.08463, 1.30038, 1.51612, 1.73187, 1.94761, 0.99905, 
      1.19626, 1.39346, 1.59067, 1.78788, 0.91255, 1.09283, 
      1.2731 , 1.45337, 1.63365, 0.82706, 0.99181, 1.15656, 
      1.32131, 1.48605, 0.74381, 0.89429, 1.04477, 1.19525, 
      1.34572] 

def make_df(data): 
    x = [1.1, 1.11, 1.12, 1.13, 1.14] 
    y = [20, 40, 60, 80, 100] 
    z = np.array(data).reshape((len(x),len(y))) 
    return pd.DataFrame(z, index=x, columns=y).reset_index().rename(columns={'index':'x'}) 

sample4 = make_df(sample4_z) 
test5 = make_df(test5_z) 
test6 = make_df(test6_z) 

現在上繪製一個3D網格中的所有三個數據幀:

# signal to pyplot that we want 3d plots 
fig, ax = plt.subplots(1, 1, figsize=(10, 10), subplot_kw={'projection': '3d'}) 

# convenience wrapper for plotting function 
def plot_3d(df): 
    ax.plot(df.x, df.y.astype(float), df.z) # dims must be floats 

# reshape with melt(), then plot 
plot_3d(pd.melt(sample4, id_vars='x', var_name='y', value_name='z')) 
plot_3d(pd.melt(test5, id_vars='x', var_name='y', value_name='z')) 
plot_3d(pd.melt(test6, id_vars='x', var_name='y', value_name='z')) 

# label axes 
ax.set_xlabel('x', fontsize=20) 
ax.set_ylabel('y', fontsize=20) 
ax.set_zlabel('z', fontsize=20) 

# optional view configurations 
ax.elev = 10 
ax.axim = 20 

3d plot

UPDATE重新:Y軸作爲分類
只有兩個連續值的軸,它通常是n不需要(也不推薦)調用3D繪圖表面(例如,參見this similar discussion)。將分類變量編碼爲標註維度更清楚。

這種情況下,由樣本組級別複雜化,這代表了第四個維度。我建議考慮一組情節,以y軸分類編碼爲傳說。就像這樣:

datasets = ['sample4','test5','test6'] 
line_types = ['-.','--','-'] 
fix, axes = plt.subplots(1,3, figsize=(14,5)) 
for i, data in enumerate([sample4, test5, test6]): 
    data.set_index('x').plot(style=line_types[i], ax=axes[i], sharey=True, 
          xticks=data.x, title=datasets[i]) 

panel plots

不過,如果你真的想保持對事物的3D,用正確的視圖旋轉的散點圖會給你你正在尋找的效果。這也避免了y軸被讀作度量變量的問題,而不是序數變量。

# scatter plot with categorical y-axis 
def plot_3d(df, color): 
    ax.scatter(df.x, df.y, df.z, c=color) # dims must be floats 

# reshape with melt(), then plot 
plot_3d(pd.melt(sample4, id_vars='x', var_name='y', value_name='z'), 'red') 
plot_3d(pd.melt(test5, id_vars='x', var_name='y', value_name='z'), 'blue') 
plot_3d(pd.melt(test6, id_vars='x', var_name='y', value_name='z'), 'green') 

# label axes 
ax.set_xlabel('x', fontsize=20) 
ax.set_ylabel('y', fontsize=20) 
ax.set_zlabel('z', fontsize=20) 

# optional view configurations 
ax.elev = 10 
ax.azim = 280 

3d scatter plot

注:這是可能的使用bar3d類來處理一個或多個維度的分類,但其級聯方法進行多點具有相同類別值可能不會得到你,你在做什麼尋找。

+0

哇!非常感謝!是否有可能在y方向上分開線條?例如,現在紅線沿着y軸是連續的,我想根據y軸值將它們分開。 –

+0

查看我更新的答案。TL; DR - 這是可能的,但它可能不是最好的方法來數據這裏。 –

+0

再一次,非常感謝你! –