2010-11-26 128 views
33

鉴于Graphics对象,我如何确定包含所有图形所需的坐标范围?基本上我需要类似默认的Show,但我想明确指定PlotRangePlotRangePaddingImagePadding如何确定PlotRange以包含所有图形?

例,空两个Show S的关系呈现相同的

g = Graphics[{Thickness[1], CapForm["Round"], Line[{{0, 0}, {1, 1}}]}]; 
Show[g] 
Show[g, PlotRange -> getPlotRange[g], PlotRangePadding->getPlotRangePadding[g], ImagePadding->getImagePadding[g]] 

动机:固定图在this问题

更新AbsoluteOptions给我PlotRange而不是其他两个选项。明确指定ImagePadding->Automatic默认情况下会改变外观,尽管它应该是Automatic。下图显示不同

两个图像,我不明白为什么

g = Graphics[{Thickness[1], CapForm["Round"], Line[{{0, 0}, {1, 1}}]}]; 
Show[g] 
Show[g, Sequence @@ AbsoluteOptions[Show[g]]] 

更新2: 类似的问题是brought up一年前,没有提出解决方案,而不是固定为数学8.0 。总结

  1. 没有办法重现Show[g]以上的PlotRange
  2. 明确的设置有没有办法让通过Show[g]
  3. Show[g,PlotRange->Automatic]使用绝对ImagePadding看起来与Show[g]
  4. AbsoluteOptions不同可以给wrong resultPlotRange
+1

我也在玩AbsoluteOptions,但有时候它会返回错误的值 – 2010-11-26 23:35:15

+0

是的......也许我更擅长实现我自己的粗线...... – 2010-11-26 23:57:53

+1

似乎问题不是新的http://thedailyreviewer.com/ compsys/view/problems-absolute-plotrange-108108947 – 2010-11-26 23:59:21

回答

3

我也有时会发现,如何让Mathematica以一致的方式显示Graphics,特别是在嵌入图形时,会感到困惑。

对于指定图形g,您提供的PlotRange的内容无关紧要,因为Thickness[1]总是绘制一条厚度等于水平绘图范围的线条。在你的榜样,Show[g, ___]给出正确的结果:

automatic image padding

Show[g],或者干脆g,是不正常的。

为什么?

我不知道在哪里/如果这是记录,但这里有几件事情,可能是相关的问题。

  1. 显然DisplayForm[Graphics[___]]是一个栅格。

  2. 我们可以得到使用栅格化[G]为g的光栅。什么是RasterSize?从试用和 错误,我发现RasterSize是10 *屏幕分辨率(在我的系统中报告为每英寸72像素)。我怎么知道这个?如果我用小于718的分辨率对g进行栅格化,则会得到尺寸为{360,361}的图像,而g中的默认图像尺寸为360像素,因此我想显示[]图形,Mathematica Rasterize 10倍的屏幕分辨率。有人知道这是否属实?你可以从Options Inspector获得你的屏幕分辨率(至少在Mathematica看到它的时候)。 编辑 那下面的表达式的计算结果为True似乎表明,显示的图形是在IMAGESIZE光栅化:使用PlotRangeImportString[ExportString[Show[g,ImageSize->100],"PNG"]] === ImportString[ExportString[Rasterize[g,RasterSize->100,ImageSize->100],"PNG"]

  3. 要重现Show[g]我需要使用 Show[g,PlotRange->{{0,1},{0,1}},ImagePadding->90.3]

specific image padding

to ge将它剪切到生产线的周边。所以看起来Mathematica说的是当使用AbsoluteOptions[]PlotRange{{0,1},{0,1}}。它不报告ImagePadding的实际值。也许是因为ImagePadding->Automatic基于使用当前的ImageSizePlotRangeClipping,...设置的规则? 90.3的ImagePadding只适用于ImageSize->360;设置ImageSize->200使得ImagePadding值错误。对于您的图形,ImagePadding->90.3*OptionValue[ImageSize]/360在我的系统上重现了Show[g,ImageSize->_]

这就是我迄今发现的。

3

您可以尝试在已知位置添加可识别的对象,然后查看它在导出版本中的显示位置以提供比例参考。我认为矢量导出(SVG或EPS)会更容易解析,但我认为在玩了一下之后栅格更容易。

例如,添加绿色矩形覆盖理论曲线范围:

g = Graphics[{Blue, Thickness[1], CapForm["Round"], 
    Line[{{0, 0}, {1, 1}}], Green, Rectangle[{0, 0}, {1, 1}]}]; 

enter image description here

im = Rasterize[g, ImageSize -> 360]; 
xy = Transpose[Position[ImageData[im], {0., 1., 0.}]]; 
pad = Map[{Min[#1], 360 - Max[#1] } &, xy]; 
Show[g, ImagePadding -> pad] 

该代码是基本上查明所有绿色像素。 这种情况下的填充是{{92,92},{92,92}},但它不需要是对称的。

5

我可以建议以下Ticks黑客:

pl = Plot[Sin[x], {x, 0, 10}]; 
Reap[Rasterize[Show[pl, Ticks -> {Sow[{##}] &, Sow[{##}] &}, ImageSize -> 0], 
    ImageResolution -> 1]][[2, 1]] 

=> {{-0.208333, 10.2083}, {-1.04167, 1.04167}} 

的诀窍是真正的PlotRange由前端决定,而不是由内核。因此,我们必须强制FrontEnd渲染图形以获得评估的滴答函数。这个黑客给出了完整的PlotRange明确的值增加了PlotRangePadding

更通用的解决方案考虑一种可能性,即plDisplayFinction选择非标值,它可能已经Axes选项设置为False

completePlotRange[plot:(_Graphics|_Graphics3D|_Graph)] := 
[email protected]@ 
    [email protected][ 
    Rasterize[ 
     Show[plot, Axes -> True, Frame -> False, Ticks -> (Sow[{##}] &), 
     DisplayFunction -> Identity, ImageSize -> 0], ImageResolution -> 1]] 

人们可以得到确切的PlotRange(不PlotRangePadding加)用下面的函数:

plotRange[plot : (_Graphics | _Graphics3D | _Graph)] := 
[email protected]@ 
    [email protected][ 
    Rasterize[ 
     Show[plot, PlotRangePadding -> None, Axes -> True, Frame -> False, 
     Ticks -> (Sow[{##}] &), DisplayFunction -> Identity, ImageSize -> 0], 
     ImageResolution -> 1]] 

P.S.论“更多信息”下PlotRange文档页面,我们可以读到:“AbsoluteOptions给出了由数学时给出的设置是AutomaticAll内部使用选项的实际设置。”(重点煤矿)。因此,如果文档不是AutomaticAll,那么文档似乎甚至不保证AbsoluteOptions将为PlotRange提供正确的值。