以下是一種方法,使用melt
和Axes3D
。
首先,生成由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](https://i.stack.imgur.com/FRBzf.png)
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](https://i.stack.imgur.com/bxHYu.png)
不過,如果你真的想保持對事物的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](https://i.stack.imgur.com/3DSGB.png)
注:這是可能的使用bar3d
類來處理一個或多個維度的分類,但其級聯方法進行多點具有相同類別值可能不會得到你,你在做什麼尋找。
哇!非常感謝!是否有可能在y方向上分開線條?例如,現在紅線沿着y軸是連續的,我想根據y軸值將它們分開。 –
查看我更新的答案。TL; DR - 這是可能的,但它可能不是最好的方法來數據這裏。 –
再一次,非常感謝你! –