Matplotlib绘制顶点面定义的双圆出现异常连接问题排查
问题描述
尝试使用Matplotlib绘制两个不同半径的圆,通过顶点(vertices)和面(faces)进行定义,采用PyTorch与Matplotlib结合实现,但运行后出现异常:两个圆之间被错误连接,而面数据(FT)中并无连接两个圆的面,请问问题原因是什么?
原代码
r2,r3=2,3 n_t3=5 n_t2=n_t2 theta_t3=torch.linspace(0,2*torch.pi,n_t3,device=torchdeviceId) VT3 = torch.stack((r3*torch.cos(theta_t3),r3*torch.sin(theta_t3)),dim=1) theta_t2=torch.linspace(0,2*torch.pi,n_t2,device=torchdeviceId) VT2 = torch.stack((r2*torch.cos(theta_t2),r2*torch.sin(theta_t2)),dim=1) VT=torch.vstack((VT2,VT3)) FT3 = torch.cat((torch.arange(0,n_t3-1).reshape(n_t3-1,1),torch.arange(1,n_t3).reshape(n_t3-1,1)),dim=1) FT2 = torch.cat((torch.arange(n_t3,n_t3+n_t2-1).reshape(n_t2-1,1),torch.arange(n_t3+1,n_t3+n_t2).reshape(n_t2-1,1)),dim=1) FT=torch.vstack((FT2,FT3)).to(torchdeviceId) xt, yt = ( VT[FT,0].detach().cpu().numpy(), VT[FT,1].detach().cpu().numpy(), ) plt.figure() plt.plot(xt,yt,label='target',marker='x',markersize=10,alpha=0.2,lw=10); plt.show()
问题原因
- Matplotlib绘图逻辑特性:当把二维数组传入
plt.plot()时,函数会默认将所有数据点按一维顺序依次连接——包括不同边段的末尾与开头。你的xt和yt是形状为[总边数, 2]的二维数组,plt.plot会先绘制所有边的起点到终点,随后自动把最后一条边的终点和第一条边的起点连接,从而产生两个圆之间的错误连线。 - 代码笔误:
n_t2=n_t2属于无效赋值,会直接导致变量未定义的运行错误,必须给n_t2指定具体数值。 - 图形不完整:原代码只生成了每个圆的
n-1条边,缺少最后一个顶点到第一个顶点的连接,导致圆本身处于未闭合状态。
修正方案
循环遍历每条边单独绘制,避免跨边连接,同时补上圆的闭合边,修正笔误:
import torch import matplotlib.pyplot as plt # 指定计算设备,可改为cuda torchdeviceId = torch.device("cpu") r2, r3 = 2, 3 n_t3 = 5 n_t2 = 5 # 修正笔误,赋值n_t2 # 生成两个圆的顶点 theta_t3 = torch.linspace(0, 2*torch.pi, n_t3, device=torchdeviceId) VT3 = torch.stack((r3*torch.cos(theta_t3), r3*torch.sin(theta_t3)), dim=1) theta_t2 = torch.linspace(0, 2*torch.pi, n_t2, device=torchdeviceId) VT2 = torch.stack((r2*torch.cos(theta_t2), r2*torch.sin(theta_t2)), dim=1) VT = torch.vstack((VT2, VT3)) # 生成边数据 FT3 = torch.cat((torch.arange(0, n_t3-1).reshape(n_t3-1, 1), torch.arange(1, n_t3).reshape(n_t3-1, 1)), dim=1) FT2 = torch.cat((torch.arange(n_t3, n_t3+n_t2-1).reshape(n_t2-1, 1), torch.arange(n_t3+1, n_t3+n_t2).reshape(n_t2-1, 1)), dim=1) FT = torch.vstack((FT2, FT3)).to(torchdeviceId) plt.figure() # 遍历每条边单独绘制 for edge in FT: x = VT[edge, 0].detach().cpu().numpy() y = VT[edge, 1].detach().cpu().numpy() plt.plot(x, y, marker='x', markersize=10, alpha=0.2, lw=10) # 补充内圆的闭合边 inner_close = torch.tensor([n_t2-1, 0], device=torchdeviceId) x = VT[inner_close, 0].detach().cpu().numpy() y = VT[inner_close, 1].detach().cpu().numpy() plt.plot(x, y, marker='x', markersize=10, alpha=0.2, lw=10) # 补充外圆的闭合边 outer_close = torch.tensor([n_t3 + n_t2 - 1, n_t3], device=torchdeviceId) x = VT[outer_close, 0].detach().cpu().numpy() y = VT[outer_close, 1].detach().cpu().numpy() plt.plot(x, y, marker='x', markersize=10, alpha=0.2, lw=10) plt.legend(['target']) plt.axis('equal') # 保证圆形比例正确,不被拉伸 plt.show()
修正说明
- 修复了
n_t2=n_t2的无效赋值问题 - 通过循环单独绘制每条边,彻底避免不同边之间的错误连接
- 补充了两个圆的闭合边,让图形完整
- 添加
plt.axis('equal')确保圆的显示比例正确
内容的提问来源于stack exchange,提问作者Cantor
相关产品推荐
相关产品推荐

