Python matplotlib绘制点云3D散点图仅显示2点的问题排查
点云3D散点图仅显示2个点问题排查
问题现象
基于点云数据绘制3D散点图时,最终生成的图表仅显示2个点。本次使用的点云数据共171行,包含224组由5个参数(x,y,z,intensity,noise)组成的参数组合,原有实现代码如下:
import pandas as pd import matplotlib.pyplot as plt import numpy as np df1 = pd.read_csv('cloud.txt',delimiter='\t',skipinitialspace=True) df1.dropna() #mojpoklusaj print(type(df1)) pd.set_option('display.max_columns', None) df1 = df1.apply (pd.to_numeric, errors='coerce') #cloud.dropna() df1.fillna(0,axis=0,inplace=True) print(len(df1.columns)) x_list = [] y_list = [] z_list = [] for x in range(1,1121): converted_list = df1.iloc[:,x].tolist() for index in range(len(converted_list)): point = converted_list[index] #np.log(point**10) modul = index % 5 if modul == 0: x_list.append(point) elif modul == 1: y_list.append(point) elif modul == 2: z_list.append(point) else: continue #df = pd.DataFrame(data) #print(type(df)) #print(df1) #d_list = list(df1.columns.values) #print(d_list) #print(type(df1)) #x = d_list[0] #y = df1[1].tolist() #z = df1[2].tolist() fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.scatter( z_list, y_list, x_list, c=z_list, cmap='viridis', linewidth=1) plt.show()
异常根因
- 列索引遍历越界:代码使用
range(1,1121)遍历列,实际读入的DataFrame列数远小于1120,遍历过程会触发索引错误,且跳过了第0列的有效数据。 - 坐标拆分逻辑错位:代码按行索引取模5拆分x/y/z值,和点云数据的存储结构不匹配——点云的5个参数为连续排布的一维序列,并非按行循环排列,导致绝大多数有效坐标被丢弃,仅偶然匹配到2个有效坐标点。
- 空值处理未生效:
df1.dropna()未将处理结果赋值回原变量,空值清洗逻辑没有实际作用。 - 散点坐标传参顺序错误:
scatter()方法传入顺序为z_list, y_list, x_list,和3D坐标轴x/y/z的定义顺序不匹配,会导致坐标位置颠倒。
修正后代码
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 读入点云数据 df1 = pd.read_csv('cloud.txt', delimiter='\t', skipinitialspace=True) # 统一转数值类型,修正空值处理逻辑 df1 = df1.apply(pd.to_numeric, errors='coerce') df1 = df1.dropna() df1.fillna(0, inplace=True) # 将二维表格展平为一维数值序列,按5个参数一组的规则拆分坐标 all_values = df1.to_numpy().flatten() # 按步长5切片提取对应坐标:每组第1位为x,第2位为y,第3位为z x_list = all_values[::5] y_list = all_values[1::5] z_list = all_values[2::5] # 如需使用强度、噪声字段可通过如下逻辑提取 # intensity = all_values[3::5] # noise = all_values[4::5] # 绘制3D散点图 fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.scatter(x_list, y_list, z_list, c=z_list, cmap='viridis', linewidth=1) plt.show()
修正说明
- 移除越界的列遍历逻辑,直接将DataFrame转为numpy数组后展平为一维序列,从根源避免索引越界导致的数据丢失。
- 调整坐标提取逻辑:按照点云5参数连续存储的结构,使用固定步长切片提取x/y/z坐标,不会出现坐标错位、漏取问题,可完整提取224组点的坐标值。
- 修正空值处理逻辑,
dropna()处理后赋值回原数据框,保证空值清洗生效。 - 调整
scatter()方法的传参顺序,和x/y/z坐标轴一一对应,避免坐标位置颠倒。
内容的提问来源于stack exchange,提问作者mika hirvonen
相关产品推荐
相关产品推荐

