将字典条目绘制为 3D 绘图

问题描述 投票:0回答:1

我有一本字典,其中每个条目代表一个 pandas 数据框。该词典有 100 个条目。

数据框表示沿 X 轴给定距离内的吸收测量值,保持 Y 轴位置固定。 每个数据帧对应于不同的 Y 位置。 Y 位置之间的步长是固定的 (100μm)。

我想在单个图中将这些 DataFrame 彼此相邻地绘制,同时还考虑 Y 轴。因此创建 3D 绘图。

到目前为止,我只能在一个 2D 图中绘制所有 DataFrame。

附图显示了这个想法。 Example with only 2 dataframes

python pandas dictionary matplotlib 3d
1个回答
0
投票

请参阅下面的代码示例,其中包括一些测试数据。

代码假设所有

Absorption
条目都有一个公共 x 轴。如果每个吸收列表都记录在不同的 x 上,则需要添加额外的插值步骤以将所有数据映射到公共轴上。

import pandas as pd
import numpy as np
from mpl_toolkits import mplot3d
from matplotlib import pyplot as plt

#Synthesise data
# data_dict contains 100 dataframes, indexed data_dict[0] to data_dict[99].
# Each dataframe has 2 columns: Absorption, and the x values at which the measurement was made
np.random.seed(0)

num_x_points = 200
x_axis = np.linspace(0, 2*np.pi / 2, num_x_points)
data_dict = {}
for i in range(100):
    abs_data = (np.random.uniform(0.9, 1.1)
                - np.cos(x_axis + np.random.uniform(0, i*np.pi/180))
                ) / (0.1*i + 10)
    
    data_dict[i] = pd.DataFrame({
        'Absorption': abs_data,
        'x_axis': x_axis
    })

#Determine number of y points
num_y = len(data_dict)
#Create y axis (in um)
y_step = 100e-6
y_axis = 1e6 * np.linspace(0, num_y * y_step, num_y)

#Compile absorption lines into a single matrix
abs_lines = np.empty((num_y, len(x_axis)))
for y_idx, df in enumerate(data_dict.values()):
    abs_lines[y_idx, :] = df.Absorption.to_numpy()

#Create a meshgrid for plotting in 3D
grid_x, grid_y = np.meshgrid(x_axis, y_axis)

#You can view the data either as lines with solid colours,
# or as points coloured by absorption
view_as_scatter = True

#Make 3d figure
figsize = 8
ax = plt.figure(figsize=[figsize] * 2).add_subplot(projection='3d')
#adjust the viewing angles
ax.view_init(elev=20, azim=240, roll=0)

if view_as_scatter:
    ax.scatter3D(grid_x, grid_y, abs_lines, c=abs_lines, marker='.', s=3, cmap='brg')
else:
    for y_idx, df in enumerate(data_dict.values()):
        ax.plot3D(grid_x[y_idx, :], grid_y[y_idx, :], df.Absorption)
    
ax.set_xlabel('x')
ax.set_ylabel('y (um)')
ax.set_zlabel('absorption')
© www.soinside.com 2019 - 2024. All rights reserved.