我有一本字典,其中每个条目代表一个 pandas 数据框。该词典有 100 个条目。
数据框表示沿 X 轴给定距离内的吸收测量值,保持 Y 轴位置固定。 每个数据帧对应于不同的 Y 位置。 Y 位置之间的步长是固定的 (100μm)。
我想在单个图中将这些 DataFrame 彼此相邻地绘制,同时还考虑 Y 轴。因此创建 3D 绘图。
到目前为止,我只能在一个 2D 图中绘制所有 DataFrame。
附图显示了这个想法。
请参阅下面的代码示例,其中包括一些测试数据。
代码假设所有
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')