如何在Matplotlib的3D绘图中绘制多条分离折线
解决3D绘图中按X值分组绘制多条折线的问题
哈哈,这个场景我太熟悉了!你直接用ax.plot3D(xs,ys,zs)会把所有点按顺序连起来,自然没法得到每条x固定的独立折线。核心思路就是先把数据按xs的唯一值分组,然后每组单独调用plot3D绘制,下面给你两种实用的实现方法:
方法一:用itertools.groupby(适合数据已按X排序的情况)
你的xs是已经按相同值连续排列的([1,1,1,2,2,2,3,3,3]),刚好可以直接用groupby按x值分组:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from itertools import groupby # 定义你的数据 xs = [1,1,1,2,2,2,3,3,3] ys = [1,2,3,1,2,3,1,2,3] zs = [1,4,9,2,8,18,4,16,36] # 创建3D绘图轴 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 把三个列表打包成(x,y,z)元组,按x值分组 data = list(zip(xs, ys, zs)) for x_val, group in groupby(data, key=lambda item: item[0]): # 提取当前x值对应的y和z数据 group_ys = [item[1] for item in group] group_zs = [item[2] for item in group] # 生成和y/z长度一致的x列表(全是当前x_val) group_xs = [x_val] * len(group_ys) # 绘制这一组的折线 ax.plot3D(group_xs, group_ys, group_zs, label=f'x={x_val}') # 添加标签和图例,让图更清晰 ax.set_xlabel('X Axis') ax.set_ylabel('Y Axis') ax.set_zlabel('Z Axis') ax.legend() plt.show()
如果你的xs不是有序排列的,记得先给数据按x值排序,再用groupby:
data_sorted = sorted(data, key=lambda item: item[0]) for x_val, group in groupby(data_sorted, key=lambda item: item[0]): # 后面的代码和上面一样
方法二:用Numpy筛选(更通用,无需考虑数据顺序)
如果你习惯用Numpy处理数据,这种方法更直观,不管xs是不是有序的都能直接用:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np # 定义数据并转成Numpy数组 xs = np.array([1,1,1,2,2,2,3,3,3]) ys = np.array([1,2,3,1,2,3,1,2,3]) zs = np.array([1,4,9,2,8,18,4,16,36]) # 创建3D绘图轴 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 获取xs的所有唯一值 unique_x_values = np.unique(xs) # 循环每个唯一x值,筛选对应的y和z并绘制 for x_val in unique_x_values: # 生成筛选掩码:找到所有x等于x_val的位置 mask = xs == x_val # 提取对应的数据 filtered_y = ys[mask] filtered_z = zs[mask] # 生成对应长度的x数组 filtered_x = np.full_like(filtered_y, x_val) # 绘制折线 ax.plot3D(filtered_x, filtered_y, filtered_z, label=f'x={x_val}') # 添加标签和图例 ax.set_xlabel('X Axis') ax.set_ylabel('Y Axis') ax.set_zlabel('Z Axis') ax.legend() plt.show()
这两种方法都能实现你要的效果:每个x的唯一值对应一条独立的3D折线,不会把所有点连成一条线。你可以根据自己的代码习惯选一种就行~
内容的提问来源于stack exchange,提问作者Nightshade




