| 扬声器 |
文字稿 |
| 乔波 |
大家好,欢迎聆听我的演讲。 |
| |
本次演讲的缘起是JMP用户社区的一次讨论。安德森·梅菲尔德博士是美国国家海洋和大气管理局(NOAA)以及迈阿密大学的海洋生物学家。 |
| |
他研究珊瑚礁的健康状况。他曾在我们JMP On Air的地球日特别节目中做过演讲。他也会在本次会议上做演讲。 |
| |
所以,他在JMP用户社区的帖子中贴出了这张图片。如果你仔细看,你会发现图片上有很多代表珊瑚或珊瑚礁的图案。 |
| |
它们将多条数据整合到一张小图表中,这有点像电子游戏中的玩家统计数据。 |
| |
它们会围绕着玩家盘旋,看着玩家在场景中奔跑。所以现在你大概明白我为什么把演讲题目叫做“当电子游戏、海洋生物学家和JMP结合在一起会得到什么”了吧?那么,我们继续。 |
| |
我将要讨论的是JMP中基于游戏或受游戏启发而实现的解决方案,包括使用自定义图形脚本。 |
| |
自定义地图。接下来,我将介绍我构建的一个基于 Web 的 3D 散点图应用程序,以及如何将 JMP 数据集集成到该应用程序中。 |
| |
以下是图形脚本的示例。 |
| |
这里有一个使用自定义地图的例子。这是我的3D散点图应用程序。 |
| |
那么,我们开始吧。为了演示如何使用自定义图形脚本,我这里有一个小示例。 |
| |
当我打开 JMP 并运行 |
| |
这个小图表,实际上,我接下来要谈谈这个。 |
| |
我使用了我自己从零开始创建的虚构数据集。它主要讲述的是一群鱼从大堡礁一路游到悉尼的故事。 |
| |
所以,要进入图形脚本,你可以选择自定义。 |
| |
然后,这个小小的加号按钮可以让你添加新的脚本。它最初是空的,但我们在 JMP 中有一些示例。 |
| |
我喜欢多边形脚本,它非常简单,功能就是绘制三角形。所以如果我把它应用到我的图表上,你就能看到一个三角形了。 |
| |
我们只用了三行代码:设置透明度、设置填充颜色,然后绘制多边形。 |
| |
但我们真正想知道的是,如何将它嵌入到脚本中?最简单的办法就是点击“答案”按钮。 |
| |
然后将脚本保存到脚本窗口。脚本内容如下:首先,启动我的小型双变量平台,输入经纬度。下方是一个调度程序,其中包含一个添加图形的脚本。 |
| |
然后是样本中的三行。 |
| |
这是一个使用图形脚本的非常简单的例子。 |
| |
现在我要嵌入一个图形脚本。它会在每个数据点上方绘制悬浮的条形图。 |
| |
在这个应用程序中,我首先设置透明度,然后绘制我的小图形的背景。 |
| |
一个为了饥饿,一个为了力量,一个为了速度。 |
| |
现在我要向你们展示整个脚本,因为它依赖于其他东西。它依赖于我设置的这些常量,这些常量主要用于处理颜色、背景以及其他一些事情,比如背景等等。 |
| |
这是我的绘制条形图函数。它接受位置、长度和颜色三个参数。因此,它可以用于每个条形图。如果我运行这个脚本…… |
| |
就是这个,你看到了那个带小图案的图形。 |
| |
就像游戏里那样,每条鱼上方都悬停着健康监测器,它们顺着澳大利亚东部洋流游向悉尼。 |
| |
这将帮助你了解该函数的工作原理,基本上是一步一步地讲解。我们首先在屏幕上放置一个标记,然后为每个标记设置像素原点。 |
| |
然后我们开始绘制背景,但这需要几个步骤。第一次设置线条粗细时,你实际上什么也看不到。 |
| |
然后我们设置颜色,设为黑色。接着我们移动鼠标,画一条很粗的背景线。 |
| |
对于每个柱状图,我们要先设置柱状图的颜色,然后移动到指定位置,再画一条线。接着绘制背景,设置背景颜色,并使其与柱状图衔接。当然,其他两条线也需要重复这些步骤。 |
| |
现在你可以使用许多不同的图形函数。这里是 JSL 语法参考中的图形函数部分,你可以构建任何你想要的东西。开始吧! |
| |
接下来,我将谈谈如何使用自定义地图。 |
| |
打扰一下。 |
| |
要使用自定义地图,基本上需要提供两个表。第一个表定义了所有要使用的形状。第二个表则为这些形状命名。 |
| |
至于这个名称列,基本上你需要添加的是一个映射角色列属性,并且它的类型必须是形状名称定义。我稍后会演示给你看。 |
| |
为了举一个非常简单的例子,当然,我们需要的是大类。我将举一个非常简单的例子。 |
| |
还有一张地图,上面只有两个矩形。我这就打开那些文件。 |
| |
正如我所说,这是一张非常小的地图。为了向您展示这些坐标,我这里有一张很小的地图。 |
| |
这里有一个脚本,它基本上显示了这些要点。 |
| |
如果我选中最上面的四个,那就是上面的矩形,接下来的四个就是下面的矩形。 |
| |
上面的是体重,下面的是身高。如果你查看列属性, |
| |
这是地图角色,形状名称定义。 |
| |
地图准备好后,我们就可以开始大班授课了。 |
| |
我们不能直接重用它。首先我们需要做的是提取身高和体重这两列数据,然后将它们堆叠起来。所以我们进入表格部分。让我来堆叠它们。 |
| |
现在我得到了一个表格,其中的列是堆叠的。 |
| |
您可以看到标签的高度和宽度交替显示,为了将其连接到地图文件,我们需要添加另一个列属性。 |
| |
这个在这里,又是映射角色。但我们不会说“形状名称定义”,我们会说“形状名称用途”,我们需要选择…… |
| |
映射文件,即映射文件的名称。 |
| |
同时将列名设置为 name。 |
| |
这样就完成了。现在我们有了这些数据,就可以把它用在图表里了。 |
| |
我们要做的图表基本上是利用标签列来创建地图形状,这样就能设置顶部和底部形状,然后我们可以拖入包含所有数据的数据列。 |
| |
进入颜色角色。好了,以上就是大班所有学生的总结,但我们真正想说的是…… |
| |
每个学生一份。如果我把它拖到卷轴上,会有点挤,但我打算通过每行设置 10 层来分散开来。 |
| |
好了。这基本上就是我想要的效果。这张图表很有用。 |
| |
单独。 |
| |
现在我们来做一些更复杂的事情。 |
| |
其实,如果你要做更复杂的操作,你可能需要使用自定义地图创建插件。 |
| |
这是一个很棒的插件。它允许你拖入图像,然后沿着图像进行描摹。 |
| |
当你完成所有形状的描绘后,点击“使用随机数据完成”,它就会生成 |
| |
你需要两个形状文件,以及一个随机数据集,用于测试你的自定义地图。这里我举个例子,只设置了四个变量,其中一个位于中心。所以它基本上是我之前幻灯片中展示的地图的正方形版本。 |
| |
但这并非我们想要的结果。我们想要的是圆形的,我记得是梅菲尔德博士把它称为复杂派。 |
| |
我不知道这算不算正式术语,但我决定用脚本来构建这些东西。 |
| |
所以我想要做的就是创建形状文件,确保我得到了医生要求的东西。那就是四个形状,每个形状的中心都有一些东西。 |
| |
然后我想,嗯,我是个程序员。我喜欢多做一些事情,让程序更灵活一些。 |
| |
所以我认为可能有些人也想做同样的事情,但只有两个变量,外加一个平均值或中心变量,或者更多。 |
| |
我当时想,如果能绘制菱形或正方形等其他形状就更好了。我并非天才,只是运气好。Xan Gregg 正好回答了一个关于如何在 JMP 中绘制极坐标图的帖子。 |
| |
它来了。 |
| |
好了,就这样。 |
| |
他们想要的形状是这样的,这和我需要的形状非常相似。 |
| |
Xan 的作品真的很棒。这是一个灵活的脚本,可以实现这个功能,并在圆周上生成这些楔形,但唯一缺少的是中心点以及我想要的特定文件命名方式。 |
| |
但其实并不难。我的脚本就是用来做这个的。当你运行“复杂派”程序时,里面有这个派的配方,你打开“复杂派”制作器,然后添加一些配料。首先,你需要指定形状的数量。 |
| |
然后,你要决定是把它放在正中间,还是放在顶部,或者稍微偏向一侧。 |
| |
然后还有一个衡量平滑度的变量。 |
| |
然后,您还需要提供内半径(您想要更多填充还是更少填充)和外半径。 |
| |
当然,下一步是运行脚本,它将生成 |
| |
这些 |
| |
这里有形状文件供您选择,还可以做一个示例测试,就像自定义饼图生成器或自定义地图插件一样。这里有一个复杂饼图的示例,形状数量为 5。 |
| |
平滑度设置为 7。如果它们要……的话,用 5 或 6 可能也还可以。 |
| |
画得很小。尺寸其实并不重要,更重要的是内半径和外半径的相对大小。这和梅菲尔德博士的设想大致相同,所以我保留了内半径为4、外半径为9的设定。 |
| |
那么,让我们看看如何实际使用这些东西。就像我们在“大班级”演示中做的那样,我们需要……我们需要堆叠这些列。但有一点不同,我的 shapefile 中并没有强度和健康变量。它们实际上是 |
| |
在形状文件中,它们被命名为楔形 1、2、3 和 |
| |
中心。 |
| |
所以我需要建造一个 |
| |
文件将 |
| |
将两者联系起来。 |
| |
首先,我举一个小型学校的例子, |
| |
我通过将健康、力量、速度这几列数据堆叠在一起来实现这一点。 |
| |
这就是我要使用的形状文件……也就是名称形状文件。 |
| |
请注意它具有列属性 |
| |
地图角色, |
| |
好的,映射角色定义。 |
| |
当你制作自己的自定义形状时,这是必需的。 |
| |
所以,我构建的链接文件,也就是将列映射到形状的文件,基本上是通过列出标签来实现的。 |
| |
堆叠文件。 |
| |
然后,在另一列“形状名称”中,我列出了形状及其名称。 |
| |
现在,这里的形状名称很重要。 |
| |
有一个属性是地图角色,但这个属性是形状名称用途。 |
| |
这个数据标签列将有一个链接 ID,以便可以虚拟地连接到我的堆叠表。 |
| |
现在我已经把这些桌子都摆好了, |
| |
下一步就是实际构建图表。 |
| |
现在,操作步骤和之前类似。唯一的区别是,我不再直接将标签拖到地图形状中,而是使用虚拟连接列,将其拖到地图形状中,这样就得到了我想要的形状。接下来,我需要将数据添加到颜色列中。 |
| |
然后加上名字。我的鱼就都在这里了。 |
| |
每个图案都对应一张图。为了找到合适的渐变效果,我在这里设置渐变,就是这个效果。 |
| |
为了确保绿色效果良好,我要把颜色反转一下。 |
| |
好了,就是这样。这就是…… |
| |
这张地图本身就很有用,因为你可以查看每条鱼的状况。当然,我还想在此基础上做一些更深入的开发。 |
| |
我希望能够将这些图像添加到工具提示中。 |
| |
为了实现这一点,我们将把它制作成数据表。 |
| |
请把我之前的文件和那张图片找回来。 |
| |
所以,在这里,红色三角形下方有一个“创建数据表”的按钮。它会生成一个新的数据表。 |
| |
有了这些图片,这真的很有用,尤其是当我们把它链接回去的时候。我会把它设置成链接ID,这样我就可以从我简单的学校文件中指向它,这样我就可以让每个标记找到每个字符的图表。 |
| |
好的,我把这些内容存储在另一个文件里,我现在要打开那个文件。我把它命名为“健康图片”。 |
| |
所以我们不再需要它了。 |
| |
我们不再需要堆叠文件了。 |
| |
但我们真正需要的是我一开始提到的那个小型学校的例子。 |
| |
现在,为了让这些内容显示在屏幕上,你需要做的第一件事是…… |
| |
图表的作用是设置图像列,即虚拟列。 |
| |
如标签所示。 |
| |
你也可以用简单的图表来做到这一点。 |
| |
我们已经有一个例子了……好吧,我再打开一次。何乐而不为呢?这是我的比赛脚本,只是为了向你们展示我是从零开始的。但是,既然我已经给这一列添加了标签,现在当我把鼠标悬停在这些图表上时,你们会看到……三个 |
| |
此图形包含信息片段,您可以执行此操作并固定任意数量的字符。 |
| |
这是使用这些图形的一种方法。 |
| |
另一种方法是使用标记。 |
| |
您将看到的图形将漂浮在这些点上,并取代我之前使用的菱形。 |
| |
我会把那些健康图片、小学校的图片,甚至那张图表都带回来。 |
| |
所以现在,我们有了这些钻石。为了把它们变成这些形状, |
| |
我们不得不再增加一个。 |
| |
给这个虚拟连接栏添加一个徽章。它现在非常流行,所以可以用作标记。因此,这里会显示一个新的徽章。在我身后, |
| |
你会看到这些图像被放置在场景中。最后一点,我不太喜欢图像周围的白色部分。实际上,这是图表图像本身就包含的。 |
| |
解决这个问题的一个方法是,它有一个脚本可以找到白色区域并设置 alpha 通道,使其透明。这样我们就得到了漂亮的图表。 |
| |
是圆形,而不是方形背景。你可能还需要做的就是增大标记的粗细。 |
| |
我们最多可以做到11。 |
| |
这样看起来怎么样?跟我之前想的差不多;10个可能更好。但我喜欢11个。好了,就是这样。 |
| |
使用标记点。我们想制作一个更复杂的图表。安德森·梅菲尔德博士想要的是在标记点后面添加一个热力图。这相当复杂,但 JMP 可以处理。这实际上是一个等高线图。 |
| |
我这里有个小学校的另一种版本。但这次,我加入了海洋温度数据。 |
| |
在底部 |
| |
它们被隐藏起来,所以不会显示为实际积分。 |
| |
我已经为此创建了镜像。 |
| |
实际上,这些图像和我之前构建的图像是一样的。 |
| |
我先从……开始 |
| |
到此为止,这样我们就能清楚地看到我的最终效果了。所以,我基本上想要这些图形。 |
| |
将鼠标悬停在轮廓上,这里会出现几个图例,显示各个部分的含义。 |
| |
这应该不难。我会先放好地图,并在 x 轴和 y 轴上标出经纬度,这样就能完成一部分工作。 |
| |
所以我首先要做的就是添加轮廓。 |
| |
我们需要添加一点色彩,所以我将临时角色拖到颜色角色上,然后调整这个轮廓的色阶数。 |
| |
稍微调整一下透明度,增加一些平滑度。 |
| |
接下来我想做的就是让它稍微透明一些。 |
| |
我们不妨加上0.6。 |
| |
这和我之前的情况差不多。现在要添加标记,有两种方法。你可以按住Shift键点击这些点,或者直接拖拽。拖拽的方法如下: |
| |
然后您可以再次设置标记大小。 |
| |
这样做 |
| |
去这里,做其他操作,这次我们用10。我觉得11有点太大了。好了,看起来不错。快完成了。我们要处理这个图例。怎么把这些颜色放进去呢?嗯,我们已经有了生命值角色。 |
| |
你可以把它拖到这里角落,添加第二个颜色角色。一开始可能会弄乱你的图表。 |
| |
我们可以解决这个问题。问题在于轮廓实际上并不需要使用健康角色。所以如果我们禁用它,就能达到我们想要的效果。 |
| |
接下来,你需要给图例添加颜色。我们可以像之前一样再次进行自定义。 |
| |
这次我们打算多做一些。我想要四个标签。 |
| |
我希望它从五点开始,一直到…… |
| |
20. |
| |
哦,我也想把颜色反过来。 |
| |
好了,差不多就是这样了,快完成了。我只想再美化一下。图例里还有几处需要修改。 |
| |
所以,请前往图例设置,移除那些似乎没有太大作用的元素,并将生命值图例移到最上方。 |
| |
就是这样。所以我觉得我基本达到了我的预期目标。 |
| |
这样我就可以把它处理掉了。我觉得现在并非所有人都需要它了。 |
| |
但我还想补充一点。 |
| |
不如加上这个图例,因为之前根本看不懂这张图的每个区域分别代表什么,比如饥饿、速度、力量和健康。幸好我们现在有了图例。 |
| |
映射文件。它从列名映射到形状。 |
| |
我这就打开它一会儿。 |
| |
所以你可以看到,我已经给所有行都添加了标签,也给数据标签列添加了标签。这意味着当你创建图表时, |
| |
所有东西都会被标记出来。所以这个很简单。你只需获取形状名称并将其拖到地图角色中,我们就完成了这个图形。 |
| |
所以如果我想把它添加到我的场景中,最好的方法就是选中它,点击加号,然后复制它。 |
| |
然后你打开一个图像编辑软件,把它保存到磁盘。当然,我已经这么做了。所以我接下来要…… |
| |
一旦你有了那个,就显示出来,我需要再次调出我的图形。 |
| |
哇,我可以直接把它拖进去。 |
| |
找到了。哦,不在那里。好吧,其实还有办法找到它。去自定义设置里,它被放到背景里了,因为通常情况下,拖入图片时,拖入的也是背景图片。 |
| |
所以现在我们只需要……先把这个挪开,这样你就能看清发生了什么……走到前面去。来了。 |
| |
好了,就在前面。我想稍微增加一点透明度,因为我觉得它有点太亮了。 |
| |
所以我们设为0.8。 |
| |
现在我们只需要把它拖到角落里,就差不多完成了。 |
| |
好的,工作量很大,涉及很多文件。我们来总结一下所有用到的文件。我用我开发的复杂饼图生成器生成了所需的两个地图文件(形状文件)。我选取了小块区域并进行了堆叠。 |
| |
我创建了这一列来格式化映射文件,该文件需要指向具有映射角色的名称文件。我使用链接引用执行虚拟连接,返回到小型学校堆叠表。 |
| |
然后我制作了一个图形,我想把它转换成数据表并保存到我的健康图像.jmp 文件中。 |
| |
当然,这必须通过虚拟方式与最初的小学校连接起来,这样我才能用它制作图形。 |
| |
然后,我对小型学校的海洋温度做了同样的事情,我的健康图片链接参考。 |
| |
我只是……我把我的列转换成形状文件,然后绘制了图例,用来表示我尝试制作的海洋温度图表,我基本上就是把它拖进去的。 |
| |
好了,我想做的二维演示就到此为止了。我们稍作休息,接下来我们将进入三维世界,甚至包括网络世界。 |
| |
应用。 |
| |
好的。 |
| |
这是我的网页版 3D 散点图应用程序。 |
| |
接下来我要向你们展示的是如何将 JMP 中的数据导入到这个软件中。 |
| |
我的应用程序是基于 JMP 的 3D 散点图的。所以这里只是为了让您回忆一下它的样子。 |
| |
现在我这里有个小演示。 |
| |
所以基本上,它有……我将向您展示一些功能,首先是能够选择不同的数据集。这是钻石数据集。 |
| |
当然,还有这些绘图点。这就是关键所在。它们是用这种小球形状绘制的,我稍后会解释它是怎么做的。 |
| |
但你还可以像在 JMP 中一样旋转它,还可以缩放、前后移动它。 |
| |
它还带有悬停标签。你可以看到右下角我画了坐标轴和网格,并做了一些自定义设置。不多。 |
| |
你可以更改背景,设置墙壁颜色。我们来看看能不能加点蓝色。 |
| |
或许您不太喜欢这样。但这只是个演示。之后您可以调整标记的大小。 |
| |
网上已经有了。 |
| |
好的,当我开始开发这个应用程序时,我首先想知道的是,它能否在网页上运行?它在我的 iPhone 或 iPad 上能否流畅运行? |
| |
因为那些机器的性能不如我的台式机。所以我创建了内置的 3D 模型,或者说是三个随机数据集,每个数据集的点数递增。然后我使用了…… |
| |
我当时觉得在低功耗设备上尝试 25,000 毫安时比较合适,但实际上在高功率设备上你可以尝试更高的毫安时。 |
| |
然后我想,好吧,我应该尝试引入一些真实的数据,于是我找到了著名的鸢尾花数据集,它是 CSV(逗号分隔变量)格式的。 |
| |
我把它导入进来了。但我必须编写一些代码才能将其转换为我的内部结构。 |
| |
我当时想,JMP有很多数据集,我还是直接导入这些数据集比较好。所以我导入了汽车、钻石和流式细胞术的数据。唯一的区别是流式细胞术的数据不太理想。 |
| |
由于涉及到使用颜色,他们不得不修改我的应用程序,使其能够接受一个没有任何颜色的图表。 |
| |
这个应用非常简单,只有一个页面,就是一个单页网页应用。只有一个HTML文件,几个JavaScript文件,还用到了一些第三方库、一种字体和一个纹理,纹理是一个用来表示形状的球体。 |
| |
我从游戏行业借鉴的技术是粒子系统。它们在模拟游戏和3D可视化中应用非常广泛。你可以用它们做出一些很酷的效果,比如火焰、烟雾、烟花和云。 |
| |
我之前曾花过一段时间参与商业游戏引擎的开发,我的职责是改进粒子系统。 |
| |
所以,我之前确实有一些这方面的经验。嗯,那是在 C++ 领域,不是 JavaScript。不过,由于我从事交互式 HTML5 和 JMP 开发已经有一段时间了,我觉得是时候看看自己能否胜任了。 |
| |
我将自己的两大爱好结合起来,开发了一个基于 Web 的粒子系统版本。我很幸运,找到了 Three.js 这个库。 |
| |
它支持硬件加速的 3D 绘图,并且拥有优秀的文档和大量的代码示例,包括粒子系统,这使得构建我的应用程序变得非常容易。 |
| |
实际上,对我来说最困难的部分是如何从 JMP 将数据导入其中。 |
| |
但我会……我会分享相关的脚本。我做的一件事就是确保这些对象的使用非常便捷。 |
| |
在我的应用程序中,我创建了一个 JavaScript 对象数组,并为数值列添加了最小值和最大值,这样我就不必在 JavaScript 中计算了。当然,JMP 在计算这类数据方面非常出色。 |
| |
嗯,对于类别,也就是颜色列,我需要做的就是使用一个类别字典。基本上,就是把所有类别的名称放在一个列表中,然后通过从零开始的索引来指向这些值。这就是这种结构的工作原理。 |
| |
我想做一个用户界面。实际上,这很容易做到。我马上就给你演示一下。基本上,我只需要把 x、y 和 z 列限制为数值即可。 |
| |
然后将其限制为颜色角色的分类列。 |
| |
那么我们来看一下这段代码。 |
| |
好的,首先我举一个非常简单的数据集的例子。 |
| |
然后,对话功能就很容易实现了。我使用了列对话框,分别指定了数值列和颜色列的设置,并确保建模类型为分类数据,这样它就同时具有序数和名义属性。 |
| |
接下来,我获取列数据,并构建所需的 JavaScript 对象。这是最小值和最大值字符串。而这只是构建这些对象的字符串。 |
| |
如果还有颜色列,我也会做同样的处理。这稍微复杂一些,因为我需要提取这些字符串并将它们放入 JavaScript 对象中。 |
| |
最后,它只需要将此内容保存到文本文件中即可。 |
| |
那么,我们来试一试。 |
| |
当然,我会使用 Big Class,所以它会是一个很小的文件。 |
| |
和 |
| |
于是我运行了脚本。 |
| |
它问我,我的XYZ想要什么。我已经选择了身高和体重,年龄是数值列,所以我也会用它,性别很适合用来选颜色。 |
| |
这样就完成了。实际上,这里的输出结果会告诉我文件在哪里。 |
| |
我正好在下一张幻灯片上放了那部分内容。那我们来看那部分吧。 |
| |
所以,我猜你肯定一直很好奇 JavaScript 中的 Big Class 会是什么样子。这就是了。你可以看到这三个部分。 |
| |
数值列包含最小值和最大值,颜色列则包含 F 和 M 这两个类别的字典,其中 0 代表女性,1 代表男性。好了,我的精彩演讲就到此结束,希望你们喜欢。 |
| |
感谢观看,如有任何疑问,请随时提出。 |