找回密码
 注册
Simdroid-非首页
查看: 212|回复: 4

[图形图像] Mathematica Plot对象解析

[复制链接]
发表于 2011-4-29 23:43:40 | 显示全部楼层 |阅读模式 来自 LAN
本帖最后由 guocong89 于 2011-6-9 19:49 编辑

从一个简单的问题谈起。怎么样画这么一个图像?


恩,Rotate一下应该就可以了
  1. Rotate[Plot[f[x], {x, 0, 4 \[Pi]}], 90 Degree]
复制代码
但是仔细观察就会发现一个问题了,x轴是反的。怎么办呢?

想到的一个方法是Scale,把x轴Scale到-1倍就可以了。但列位试试,怎么把Scale作用到Plot上都是报错。以前也曾经试图把Plot对象和Circle,Point画在同一个Graphics里面,但是失败了。于是下决心好好研究一下Plot对象的结构,为何与其他的Graphics Primitives 差距这么大。
 楼主| 发表于 2011-4-30 00:52:20 | 显示全部楼层 来自 LAN
Simdroid开发平台
本帖最后由 guocong89 于 2011-6-9 19:52 编辑

首先使用TreeForm查看一个简单的Plot[Sin[x],{x,-1,1}]




不难发现结果是以Graphics作为根的,这个很容易理解,毕竟Plot出来的结果既含有坐标轴,又含有标签,还有数据图像,肯定是个复杂的Graphics对象,在帮助里也说得很明确,“Plot normally returns Graphics[{Line[...],...}]. ”。因此,我们就不能够把Plot结果像Disk,Arrow一样插入到Graphics中,因为它自己本身就是Graphics对象。同时,针对graphics primitive的函数也都不能直接作用在Plot结果上,比如上面提到的Scale。

往下看,Graphics包含了两个List,前者是Primitive对象,后者是属性列表,这和我们平时生成Graphics的方法是一致的,它本来就是Graphics嘛。



如上图,我们只看前一个List,它也只包含一个List。那么这一层是什么呢?这一层的List之后就可以看到我的图线了,是处于第三层的一个List包含了Hue和Line两个元素。那么第二层的我们试着同时绘制两条图线,TreeForm@Plot[{x, Sin[x]}, {x, -1, 1}],会发现新添加的图线也是处于第三层,第二层依然是只有一个孤零零的List。
回复 不支持

使用道具 举报

 楼主| 发表于 2011-4-30 02:42:55 | 显示全部楼层 来自 LAN
本帖最后由 guocong89 于 2011-6-9 19:55 编辑

我猜测这是和Show有关,实地测试:
  1. Show[Plot[Sin[x], {x, -1, 1}], Plot[Cos[x], {x, 0, 2}]] // TreeForm
复制代码


但是不给力的是,现在包含Line的List降到了第4层。这个我们暂且不关心了。我们继续观察这个树结构会发现,Show的两个子图像x和Cos[x]设置了不同的PlotRange,但是Show之后到了Graphics里面就被合并了,放到了参数子树里面,独立于前面的Primitive之外,因此说,Show里的多个Graphics对统一参数设置不同的值,最终只有一个值是有效的,这和Show的帮助说明相一致的
回复 不支持

使用道具 举报

 楼主| 发表于 2011-4-30 03:00:04 | 显示全部楼层 来自 LAN
本帖最后由 guocong89 于 2011-4-30 03:50 编辑

至此,我们基本了解Plot结果的大致结构了,Plot可以看作是一种特殊的Graphics求值器,现根据函数式求出散点序列,转换为Line对象,然后填充到一个Graphics对象里。Plot的那些Axes,Epilog,PlotRange属性,其实是来自于Graphics而已。如果想要把Plot和Circle放到一起,就不能够想当然的把Plot放到Graphics里面了,因为Graphics是不支持嵌套的,可行方法有以下几种
  1. Plot[Sin[x], {x, -1, 1}, Epilog -> Circle[{0, 0}, 0.1]]
复制代码
  1. Show[Plot[Sin[x], {x, -1, 1}], Graphics[Circle[{0, 0}, 0.1]]]
复制代码
  1. Graphics[{Circle[{0, 0}, 0.1],
  2.   Inset[Plot[Sin[x], {x, -1, 1}], {0, 0}, {0, 0}, {1, 1}]}]
复制代码
那么我们如果只想操纵图线而不管坐标轴呢?根据最早的那张图片,不难得出以下的提取步骤
  1. Plot[Sin[x], {x, 0, 4 \[Pi]}] // First // First // Last // Last
复制代码
或者
  1. Plot[Sin[x], {x, 0, 4 \[Pi]}] // Cases[#, Line[___], Infinity] &
复制代码
回到我们最早的那个问题,现在可以就很容易的解决掉了
  1. a = Plot[Sin[x], {x, -4 \[Pi], 4 \[Pi]}] //    Cases[#, Line[___], Infinity] &;Graphics[{Blue, Thick, Rotate[a, 90 Degree, {0, 0}]}, Axes -> True,  Ticks -> {{-\[Pi], \[Pi]}, Range[-4 \[Pi], 4 \[Pi], \[Pi]]},  PlotRange -> {{-\[Pi], \[Pi]}, Automatic}]
复制代码
回复 不支持

使用道具 举报

发表于 2011-4-30 18:09:14 | 显示全部楼层 来自 台湾

  1. ListLinePlot[Transpose[{{#[[1]],#[[2]]},{#[[2]],-#[[1]]}}&/@
  2. Plot[Sin[x],{x,-4\[Pi],4\[Pi]}][[1,1,-1,2,1]]],
  3. PlotStyle->{{Thickness[0.025],Red},{Thickness[0.025],Blue}},
  4. AspectRatio->4,PlotRange->{{-Pi,Pi},{-4Pi,4Pi}},
  5. Ticks->{{-Pi,Pi},Range[-4Pi,4Pi,Pi]}
  6. ]
复制代码
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-4-28 16:05 , Processed in 0.035215 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表