工程邮袋
第 3 集:John Jacob Jingleheimer……史密斯图表!
我们系统工程师时不时会遇到一些有趣的问题,这些问题在一定程度上超出了我们的典型范围。 JMP用法。 这些应用程序通常很聪明,而且很多时候让人们明白如何使用数据不仅仅是为了解决业务或技术问题。 其他时候,这些问题只是出乎意料的、具有挑战性的问题。 我称这些为“曲线球”。
我喜欢一个好的曲线球。
我想分享这个特别的原因有几个。 首先,这是一个如何重新利用图形自定义来实现目标的示例。 其次,我将说明我在解决问题时所经历的思考过程JMP . 简而言之,这是旅程比结果更具启发性的案例之一。 因此,无需进一步限定,以下是来自纽约州的另一位同事的一个非常好的曲线球示例,我认为分享它会很有趣。
......并且为了记录,尼克,这不是一个“快速的问题”! ;D
问题
迈克 [JMP],快速提问——您知道是否存在用于绘制极坐标类型图形的 JMP 插件或脚本? 即在史密斯图上做等高线图,下面粘贴的例子,用于一些射频阻抗分析.... 我们现在可以忍受转换为直角坐标,但认为值得询问您是否以前见过它或认识 JMP 的某个人可能会提供帮助。


史密斯图模板 - 有没有办法在史密斯图上绘制两个数据字段(实坐标值和虚坐标值)?
在谷歌上找到了一个等高线图的例子。 似乎 JMP 可以做一些事情……
谢谢,
尼克 [用户]
我的回复:
嗨,尼克,你能分享你用来制作等高线图的数据吗?
我可能能够创建一个符合在数据顶部覆盖网格的要求的 shapefile。 (没有承诺,但我需要数据来交叉检查我是否做得正确。)
最好的,
米
史密斯圆图是什么鬼?
这正是我看到这个问题时的想法。 老实说,我在社区看到过他提到的问题。 我看了一眼社区问题,然后想,“不。 那是给别人的。”显然,生活有其他想法。 因此,经过适当的惩罚,我开始弄清楚这些情节是什么。 这是非常有趣的阅读,但说实话,细节对于这个讨论真的无关紧要。
在高层次上,史密斯圆图是一种用于电气工程的极坐标图。 (这对我来说很有意义。 ) 事实证明,它们由重叠的圆和圆弧组成,其中给定圆的半径与测量的物理量有关。 (再一次 - 没问题,特别是因为一位善良的教授在他们的网站上发布了他们的讲义,其中包括将物理量与圆半径联系起来所需的方程。 )此外,使用这些东西的人将数据从极坐标系(以半径和角度绘制的数据点)转换为笛卡尔系统(以 x 和 y 绘制的数据点)以便于绘制是很常见的。
开发过程
当我完成研究时,我发现我需要以某种方式构建一组具有特定半径的圆,并且我需要这些半径与用户提供的一组数据相匹配。 我考虑得越多,我最初为 Graph Builder 构建 shapefile 的想法似乎就越不合适。 一位同事进一步证实了这一点,他认为这是有问题的。 但为什么? 好吧,首先,必须将数据重新缩放到与 shapefile 坐标系相同的比例。 即使有详细的文档,这似乎也是一个问题的雷区。 最终,我要么构建一个完全独立的插件,在幕后扩展所有内容,要么构建 shapefile,将其扔到栅栏上,并希望它运行时没有问题。 我对这些选择中的任何一个都不疯狂。 其次,我必须弄清楚如何将这些弧设置为正确地在与圆圈的交叉点处开始和结束。 这不是一件容易的事。
证据表明我不得不放弃我最初的想法——甚至在我得到我要求的数据之前! 我会从这里去哪里? 回到起点! 我从一个简单的问题开始重新提出我的问题。
- 我可以绘制数据吗? 是的,因为我可以预期用户会将数据转换为笛卡尔坐标,所以我可以使用标准平台之一(图形生成器或等高线图)来生成数据图。
- 我需要对情节做些什么才能使它成为史密斯图?我需要创建一系列圆、弧和线并标记它们。
- 我如何绘制所有这些?我有两个选择。 Graph Builder 可以让我使用 shapefile,但我们已经取消了该选项。 shapefile 也不会让我轻松使用文本标签。 图形脚本可用于注释现有绘图,但这需要编写脚本,这可能会让用户感到害怕。
- 如果我构建一个可以做注释的小插件怎么办?我越仔细研究这个问题,我就越意识到这是我必须走的方向。 但是,我也意识到,如果我致力于创建一个插件,我可以从我最近构建的半导体工具包中回收大量支持代码。(永远保存你的代码,孩子们!)
图形脚本
在 JMP 中打开一个情节 - 任何 2D 情节....继续,我会等...。
准备好?
正确的! 右键单击图形区域并查看底部。 您看到“自定义...”选项了吗? 你有没有探索过这个选择? 大多数人没有。 我预计这会因为 JMP 14 而开始改变(边界图),但到目前为止,我认为它在 JMP 中并不是一个非常常见的使用领域。 很遗憾,因为您可以通过自定义做很多事情。 事实证明,通过将图形脚本添加到绘图的自定义项中,可以很容易地创建史密斯图。现在,你们中的一些人可能已经出冷汗了,因为我使用了“s-word”——不,不是那剑–我的意思是“脚本”。但是,请记住,我们所需要的只是圆圈、线条和标签,而这些很容易编写脚本。 我还将添加一个形状以在我们不需要的位周围创建一个蒙版,并使标签更容易看到。 以下是我们如何制作每一个,如下面的史密斯图表所示。
绘制数据
图形脚本首先需要一个图形。 所以,第 1 步(应该总是是这种情况)是绘制数据。 在这种情况下,我在等高线图中使用了一个平滑公式(更多关于这个小工作流程的信息:所有晶圆图都是错误的:半导体数据可视化的冒险)。 从那里,您打开图表的自定义项。要将图形脚本添加到自定义项中,只需按左侧图层列表中的“+”按钮。 这会在堆栈中为您提供一个新条目,并在右侧提供一个空白脚本字段。 如果需要,您可以通过双击标题来命名脚本(我建议您这样做——这只是很好的组织)。 您可以在脚本字段上方的下拉列表中探索一些模板和示例,以获取想法。 层在堆栈中出现的顺序决定了顶部的内容。 底部的图层最靠近您的眼球(注意 - 这是落后从大多数图形艺术软件所做的!)最后,当我使用一些图形脚本时,还有其他的。 它们可以在脚本指南中的图形组下找到(在 JMP - 帮助 > 脚本指南中。 选择功能类别以使其更易于查找)。
画圈
圈子使用圆({,},<半径>)图形脚本中的命令。 这是我在示例中用于圆心在 y = 0 行的圆的脚本(绿色文本描述了每个部分的作用)。
// make a list of circles using a desired step and range of resistances
inc = 0.2;
resCircs = Index( 0, 5, 0.2 );
// set line color and weight
Pen Color( "Gray" );
Pen Size( 1 );
// loop through the list of resistances, calculate and plot a circle for each one
For( i = 1, i <= N Items( resCircs ), i++,
Circle( {resCircs[i] / (1 + resCircs[i]), 0}, 1 / (1 + resCircs[i]) )
);
弧的代码实际上也是圆。 (请记住,圆弧只是圆的一部分。)不同之处在于如何计算中心和半径。 列表中的每个条目还创建了两个圆圈——一个用于正曲线,一个用于负曲线。
inc = 0.2;
reactCircs = Index( 0, 5, 0.2 );
Pen Color( "Gray" );
Pen Size( 1 );
For( i = 1, i <= N Items( reactCircs ), i++,
Circle( {1, 1 / reactCircs[i]}, 1 / reactCircs[i] );
Circle( {1, 1 / -reactCircs[i]}, 1 / -reactCircs[i] );
);
接下来,我将创建一个形状来掩盖我不需要的圆圈部分。
绘制不规则形状(多边形)
不规则形状使用多边形([],[])命令。 您还可以使用 {x,y} 表示法定义每个顶点位置,但使用起来很痛苦。 代码如下所示(为了便于阅读,删除了矩阵):
// define the fill color
Fill Color( "white" );
// define the polygon using matrices
Polygon([… xmatrix…],[…ymatrix…]);
省略的坐标定义了一个正方形,其中心有一个圆,其大小与以 y = 0 线为中心的最大圆相同。 将多边形脚本放在圆形脚本下方(即,更靠近堆栈顶部)掩盖了史密斯图不需要的圆形部分。
绘图标记和文本
标记(数据点)使用命令标记(颜色状态(<颜色>),[],[]) . 颜色状态参数是可选的,但允许您独立于任何其他脚本控制标记颜色。 将文本标签放在图表上使用文本(, {,}, ) . justification 参数是可选的,{x,y} 位置用于文本字段的中心。 在示例中,标记和文本之间的坐标是相同的,我只是合并了一些偏移和对齐调整以使事物正确对齐(这导致了最后的那个毛茸茸的 if 语句)。 为了使这更容易,我使用了一个包含 x,y 坐标和作为数字的标签的矩阵。
// coordinate matrix [x, y, label]
mat = [<MATRIX>];
// set line color and weight and the text size
Pen Color( "Gray" );
Pen Size( 1 );
Text Size( 8 );
// make the markers
Marker( Color State( "Gray" ), mat[0, 1], mat[0, 2] );
// make the labels using the matrix with some offsets and rounding
For( j = 1, j <= N Rows( mat ), j++,
If( Round( mat[j, 2], 1 ) < 0,
string = " -" || Char( Round( mat[j, 3] * 1, 2 ) ) || " ",
string = " " || Char( Round( mat[j, 3] * 1, 2 ) ) || " "
);
If(
Round( mat[j, 1], 1 ) <= 0 & Round( mat[j, 2], 1 ) > 0,
Text( Right Justified, {mat[j, 1], mat[j, 2] + 0.03}, string ),
Round( mat[j, 1], 1 ) > 0 & Round( mat[j, 2], 1 ) > 0 & mat[j, 3] <= 2,
Text( {mat[j, 1], mat[j, 2] + 0.03}, string ),
Round( mat[j, 1], 1 ) > 0 & Round( mat[j, 2], 1 ) < 0 & mat[j, 3] <= 2,
Text( {mat[j, 1], mat[j, 2] - 0.05}, string ),
Round( mat[j, 1], 1 ) <= 0 & Round( mat[j, 2], 1 ) < 0,
Text( Right Justified, {mat[j, 1], mat[j, 2] - 0.05}, string ),
Round( mat[j, 1], 1 ) <= 0 & Round( mat[j, 2], 1 ) == 0,
Text( Center Justified, {mat[j, 1], mat[j, 2] + 0.03}, string ),
Round( mat[j, 1], 1 ) > 0 & Round( mat[j, 2], 1 ) == 0 & mat[j, 3] <= 1.4,
Text( Center Justified, {mat[j, 1], mat[j, 2] + 0.03}, string )
);
);</MATRIX>
画线
一行使用命令行({,},{,}) .在示例中,我将我的行与“勘误”脚本中的其他一些零碎的内容放在一起:
// set line color and weight
Pen Color( "Gray" );
Pen Size( 1 );
// draw the line, circle, and center marker
Line( {-1, 0}, {1, 0} );
Circle( {0 / (1 + 0), 0}, 1 / (1 + 0) );
Marker( Color State( "red" ), {0, 0} );
把所有东西放在一起
使用 Semiconductor Tool Kit 的 Annotate 部分(其功能与我们在此处所做的完全相同),将计算替换为现有代码并使用 Application Builder 创建一个新的应用程序相当容易(请始终回收您的代码,伙计们) !)。 自定义作为预览应用于空白图表框。 当您对结果感到满意时,您可以单击“注释”按钮,该按钮会将图形脚本复制到绘图的自定义项中。

最后的想法
那么,我在这次小小的冒险中学到了什么? 第一——遵循事实;这包括问题的范围界定部分。 我最初的想法是完全错误的,但是当我了解它有多么错误时,我正在收集获得正确解决方案所需的信息。 第二——不要害怕烧死稻草人。 如果它不起作用,不要害怕放弃你最初的概念。 第三——我经常对自定义可以做的事情感到惊讶。
这史密斯圆图生成器插件如果你想修改它,它是可用的。
作者的注释
对于那些再次阅读本文的人,不,你不是疯了,标题确实发生了一些变化。我收到了更新标题的请求,以便我们的搜索引擎更容易找到。我只能猜测这是因为一些搜索引擎是 19 世纪参考图书馆员的现代化身,没有幽默感。对任何不便表示歉意。-M
附言对于您可能遇到的任何“John Jacob Jingleheimer Schmit”耳虫,我们深表歉意。-M。
编者注:你读过我们工程邮袋系列的其他部分? 了解 Mike 如何帮助正在使用的用户JMP决定是否注册除雪服务并为 STEAM 教育计划开发独特的可视化。