pandas多个数据帧的3D图

时间:2017-04-25 17:03:22

标签: python pandas matplotlib plot mplot3d

我的目标是绘制类似于以下link的顶部图表的内容。

我有几个txt文件,每个文件对应一个不同的样本。 目前,我将我的数据作为pandas数据帧加载(虽然我不确定如果我加载为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轴的所有数据帧,这意味着y轴应该是我所拥有的每个样本,在上面的例子中的3d图中,但我不知道如何“堆叠”数据帧并使用第三轴绘制它们。

任何帮助都将不胜感激。

提前致谢。

1 个答案:

答案 0 :(得分: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

更新 re:y轴为分类
仅使用两个连续值轴,通常不需要(也不推荐)调用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类将一个或多个维度视为分类,但是对具有相同类别值的多个点的级联方法可能无法满足您的要求。寻找。