如何用RecipesBase为两类结构体数组实现plot(nodes, elements)?
正确实现
plot(nodes, elements)的RecipesBase方案 你不需要额外定义占位结构体,直接针对Node数组和Element数组的组合编写系列配方即可,这才是匹配plot(nodes, elements)调用方式的最优方案。
具体代码实现
先假设你的自定义结构体定义如下(可根据实际字段调整):
struct Node{TF<:AbstractFloat} x::TF y::TF # 3D网格场景可添加z字段 end struct Element{TF<:AbstractFloat} node_indices::Vector{Int} # 存储元素对应的节点索引(从1开始计数) end
然后编写RecipesBase配方:
using RecipesBase # 精准匹配双参数类型的系列配方签名 @recipe function plot_mesh(nodes::Array{Node{TF},1}, elements::Array{Element{TF},1}) where TF # 设置默认绘图属性,用户调用时可直接覆盖 linewidth --> 1.2 color --> :steelblue seriestype --> :path # 面单元可改为:polygon,3D网格可改为:mesh3d # 遍历所有元素,生成单个元素的绘图坐标序列 for elem in elements # 提取当前元素对应的节点坐标 elem_coords = [(nodes[idx].x, nodes[idx].y) for idx in elem.node_indices] # 面单元需要闭合路径,保证图形完整 if plotattributes[:seriestype] == :polygon push!(elem_coords, elem_coords[1]) end # 输出单个元素的绘图数据 @series begin elem_coords end end end
你之前遗漏的关键要点
- 多参数类型精准匹配:系列配方的签名必须明确对应两个输入参数的完整类型(包括参数化的
TF),RecipesBase才能正确调度到你的配方函数,模糊的类型匹配会导致调度失败。 - @series块的使用:处理多个元素时,必须用
@series块将每个元素的绘图数据单独输出,否则所有元素会被合并成一个混乱的系列。 - 自定义数据转换:RecipesBase不会自动解析你的
Node/Element结构体内部字段,必须手动提取坐标、转换为绘图需要的格式(比如二维坐标元组的数组)。 - 属性设置的优先级:用
-->设置的是默认属性,用户调用plot(nodes, elements; linewidth=2, color=:red)时可以直接覆盖这些默认值。
使用方式
用户只需加载你的包,再加载任意Plots后端(比如GR、PyPlot),就能直接调用目标函数:
using GR # 构造测试网格数据 nodes = [Node(0.0,0.0), Node(2.0,0.0), Node(2.0,2.0), Node(0.0,2.0)] elements = [Element([1,2,3,4]), Element([1,3])] # 直接调用plot(nodes, elements) plot(nodes, elements)
内容的提问来源于stack exchange,提问作者cardoza2
相关产品推荐
相关产品推荐

