Mathematica:3D 图形中的光栅 [英] Mathematica: Rasters in 3D graphics

查看:32
本文介绍了Mathematica:3D 图形中的光栅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时导出为 pdf 图像很麻烦.如果您绘制的数据包含许多点,那么您的图形将很大,并且您选择的 pdf 查看器将花费大部分时间来渲染此高质量图像.因此,我们可以将此图像导出为 jpeg、png 或 tiff.从某个角度来看,图片会很好,但是当您放大时,它会看起来完全失真.这对于我们正在绘制的图形在某种程度上是好的,但是如果您的图像包含文本,那么该文本将看起来像素化.

There are times when exporting to a pdf image is simply troublesome. If the data you are plotting contains many points then your figure will be big in size and the pdf viewer of your choice will spend most of its time rendering this high quality image. We can thus export this image as a jpeg, png or tiff. The picture will be fine from a certain view but when you zoom in it will look all distorted. This is fine to some extent for the figure we are plotting but if your image contains text then this text will look pixelated.

为了尽量做到两全其美,我们可以将此图分为两部分:带标签的轴和 3D 图片.因此可以将轴导出为 pdf 或 eps,将 3D 图形导出为光栅.我希望我知道以后如何在 Mathematica 中将两者结合起来,所以目前我们可以使用矢量图形编辑器,例如 Inkscape 或 Illustrator 来结合两者.

In order to try to get the best of both worlds we can separate this figure into two parts: Axes with labels and the 3D picture. The axes can thus be exported as pdf or eps and the 3D figure as a raster. I wish I knew how later combine the two in Mathematica, so for the moment we can use a vector graphics editor such as Inkscape or Illustrator to combine the two.

我设法为我在出版物中制作的一个情节实现了这一点,但这促使我在 Mathematica 中创建例程以自动化此过程.这是我目前所拥有的:

I managed to achieve this for a plot I made in a publication but this prompt me to create routines in Mathematica in order to automatize this process. Here is what I have so far:

SetDirectory[NotebookDirectory[]];
SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];

我喜欢通过将工作目录设置为 notebook 目录来启动我的 notebook.由于我希望我的图像具有我指定的大小,因此我将打印样式环境设置为工作,请检查 this 了解更多信息.

I like to start my notebook by setting the working directory to the notebook directory. Since I want my images to be of the size I specify I set the printing style environment to working, check this for more info.

in = 72;
G3D = Graphics3D[
  AlignmentPoint -> Center,
  AspectRatio -> 0.925,
  Axes -> {True, True, True},
  AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}},
  AxesStyle -> Directive[10, Black],
  BaseStyle -> {FontFamily -> "Arial", FontSize -> 12},
  Boxed -> False,
  BoxRatios -> {3, 3, 1},
  LabelStyle -> Directive[Black],
  ImagePadding -> All,
  ImageSize -> 5 in,
  PlotRange -> All,
  PlotRangePadding -> None,
  TicksStyle -> Directive[10],
  ViewPoint -> {2, -2, 2},
  ViewVertical -> {0, 0, 1}
 ]

这里我们设置了我们想要制作的情节的视图.现在让我们创建我们的情节.

Here we set the view of the plot we want to make. Now lets create our plot.

g = Show[
  Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, 
   Mesh -> None,
   AxesLabel -> {"x", "y", "z"}
   ], 
  Options[G3D]
 ]

现在我们需要找到一种分离的方法.让我们从绘制轴开始.

Now we need to find a way of separating. Lets start by drawing the axes.

axes = Graphics3D[{}, AbsoluteOptions[g]]

fig = Show[g, 
  AxesStyle -> Directive[Opacity[0]],
  FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}
 ]

我包含了面网格,以便我们可以在后期编辑过程中将图形与轴匹配.现在我们导出两个图像.

I included the facegrids so that we can match the figure with the axis in the post editing process. Now we export both images.

Export["Axes.pdf", axes];
Export["Fig.pdf", Rasterize[fig, ImageResolution -> 300]];

您将获得两个 pdf 文件,您可以将它们编辑并组合成 pdf 或 eps.我希望它就那么简单,但事实并非如此.如果你真的这样做了,你会得到这个:

You will obtain two pdf files which you can edit in and put together into a pdf or eps. I wish it was that simple but it isn't. If you actually did this you will obtain this:

这两个数字大小不同.我知道axes.pdf 是正确的,因为当我在Inkspace 中打开它时,图形大小是我之前指定的5 英寸.

The two figures are different sizes. I know axes.pdf is correct because when I open it in Inkspace the figure size is 5 inches as I had previously specified.

我之前提到过,我设法通过我的一个情节获得了这一点.我将清理文件并更改图表,以便任何想要了解这是否属实的人都可以更容易地访问它.无论如何,有谁知道为什么我不能让两个 pdf 文件的大小相同?另外,请记住,我们希望为光栅化图形获得一个漂亮的图.感谢您抽出宝贵时间.

I mentioned before that I managed to get this with one of my plots. I will clean the file and change the plots to make it more accessible for anyone who wants to see that this is in fact true. In any case, does anyone know why I can't get the two pdf files to be the same size? Also, keep in mind that we want to obtain a pretty plot for the Rasterized figure. Thank you for your time.

附注.作为奖励,我们可以避免后期编辑并在 mathematica 中简单地组合两个数字吗?光栅化版本和矢量图形版本.

PS. As a bonus, can we avoid the post editing and simply combine the two figures in mathematica? The rasterized version and the vector graphics version that is.

感谢 rcollyer 的评论.我正在发布他评论的结果.

Thanks to rcollyer for his comment. I'm posting the results of his comment.

有一点需要说明的是,当我们导出轴时,我们需要将Background 设置为None,以便我们可以拥有透明的图片.

One thing to mention is that when we export the axes we need to set Background to None so that we can have a transparent picture.

Export["Axes.pdf", axes, Background -> None];
Export["Fig.pdf", Rasterize[fig, ImageResolution -> 300]];
a = Import["Axes.pdf"];
b = Import["Fig.pdf"];
Show[b, a]

然后,导出图形就得到了想要的效果

And then, exporting the figure gives the desired effect

Export["FinalFig.pdf", Show[b, a]]

轴保留了矢量图形的漂亮组件,而图形现在是我们绘制的图形的光栅化版本.但主要问题仍然存在.你如何让这两个数字匹配?

The axes preserve the nice components of vector graphics while the figure is now a Rasterized version of the what we plotted. But the main question still remains. How do you make the two figures match?

Alexey Popkov 已经回答了我的问题.我要感谢他花时间调查我的问题.以下代码是想要使用我之前提到的技术的人的示例.请参阅 Alexey Popkov 的回答以获取其代码中的有用注释.他设法让它在 Mathematica 7 中运行,在 Mathematica 8 中运行得更好.结果如下:

My question has been answered by Alexey Popkov. I would like to thank him for taking the time to look into my problem. The following code is an example for those of you want to use the technique I previously mentioned. Please see Alexey Popkov's answer for useful comments in his code. He managed to make it work in Mathematica 7 and it works even better in Mathematica 8. Here is the result:

SetDirectory[NotebookDirectory[]];
SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];
$HistoryLength = 0;
in = 72;
G3D = Graphics3D[
 AlignmentPoint -> Center, AspectRatio -> 0.925, Axes -> {True, True, True},
 AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, AxesStyle -> Directive[10, Black],
 BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, Boxed -> False, 
 BoxRatios -> {3, 3, 1}, LabelStyle -> Directive[Black], ImagePadding -> 40,
 ImageSize -> 5 in, PlotRange -> All, PlotRangePadding -> 0,
 TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, ViewVertical -> {0, 0, 1}
];
axesLabels = Graphics3D[{
 Text[Style["x axis (units)", Black, 12], Scaled[{.5, -.1, 0}], {0, 0}, {1, -.9}],
 Text[Style["y axis (units)", Black, 12], Scaled[{1.1, .5, 0}], {0, 0}, {1, .9}],
 Text[Style["z axis (units)", Black, 12], Scaled[{0, -.15, .7}], {0, 0}, {-.1, 1.5}]
}];
fig = Show[
  Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, Mesh -> None],
  ImagePadding -> {{40, 0}, {15, 0}}, Options[G3D]
];
axes = Show[
  Graphics3D[{}, FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}, 
    AbsoluteOptions[fig]], axesLabels, 
    Epilog -> Text[Style["Panel A", Bold, Black, 12], ImageScaled[{0.075, 0.975}]]
];
fig = Show[fig, AxesStyle -> Directive[Opacity[0]]];
Row[{fig, axes}]

此时您应该看到:

放大率会影响图像的分辨率.您应该尝试不同的值,看看这会如何改变您的图片.

The magnification takes care of the resolution of your image. You should try different values to see how this changes your picture.

fig = Magnify[fig, 5];
fig = Rasterize[fig, Background -> None];

组合图形

axes = First@ImportString[ExportString[axes, "PDF"], "PDF"];
result = Show[axes, Epilog -> Inset[fig, {0, 0}, {0, 0}, ImageDimensions[axes]]];

导出它们

Export["Result.pdf", result];
Export["Result.eps", result];

我使用上述代码发现 M7 和 M8 之间的唯一区别是 M7 无法正确导出 eps 文件.除此之外,现在一切正常.:)

The only difference I found between M7 and M8 using the above code is that M7 does not export the eps file correctly. Other than that everything is working fine now. :)

第一列显示从 M7 获得的输出.顶部是文件大小为 614 kb 的 eps 版本,底部是文件大小为 455 kb 的 pdf 版本.第二列显示从 M8 获得的输出.顶部是文件大小为 643 kb 的 eps 版本,底部是文件大小为 463 kb 的 pdf 版本.

The first column shows the output obtained from M7. Top is the eps version with file size of 614 kb, bottom is the pdf version with file size of 455 kb. The second column shows the output obtained from M8. Top is the eps version with file size of 643 kb, bottom is the pdf version with file size of 463 kb.

我希望你觉得这很有用.请查看 Alexey 的回答以查看其代码中的注释,它们将帮助您避免使用 Mathematica 的陷阱.

I hope you find this useful. Please check Alexey's answer to see the comments in his code, they will help you avoid pitfalls with Mathematica.

推荐答案

Mathematica 7.0.1 的完整解决方案:修复错误

带注释的代码:

(*controls the resolution of rasterized graphics*)
magnification = 5;

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"]
(*Turn off history for saving memory*)
$HistoryLength = 0;
(*Epilog will give us the bounding box of the graphics*)
g1 = Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, 
   AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImagePadding -> All, 
   ImageSize -> 5*72, PlotRange -> All, PlotRangePadding -> None, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}, AxesStyle -> Directive[Opacity[0]], 
   FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}, Mesh -> None, 
   ImagePadding -> 40, 
   Epilog -> {Red, AbsoluteThickness[1], 
     Line[{ImageScaled[{0, 0}], ImageScaled[{0, 1}], 
       ImageScaled[{1, 1}], ImageScaled[{1, 0}], 
       ImageScaled[{0, 0}]}]}];
(*The options list should NOT contain ImagePadding->Full.Even it is \
before ImagePadding->40 it is not replaced by the latter-another bug!*)
axes = Graphics3D[{Opacity[0], 
    Point[PlotRange /. AbsoluteOptions[g1] // Transpose]}, 
   AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   AxesStyle -> Directive[10, Black], 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImageSize -> 5*72, 
   PlotRange -> All, PlotRangePadding -> None, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}, ImagePadding -> 40, 
   Epilog -> {Red, AbsoluteThickness[1], 
     Line[{ImageScaled[{0, 0}], ImageScaled[{0, 1}], 
       ImageScaled[{1, 1}], ImageScaled[{1, 0}], 
       ImageScaled[{0, 0}]}]}];
(*fixing bug with ImagePadding loosed when specifyed as option in \
Plot3D*)
g1 = AppendTo[g1, ImagePadding -> 40];
(*Increasing ImageSize without damage.Explicit setting for \
ImagePadding is important (due to a bug in behavior of \
ImagePadding->Full)!*)
g1 = Magnify[g1, magnification];
g2 = Rasterize[g1, Background -> None];
(*Fixing bug with non-working option Background->None when graphics \
is Magnifyed*)
g2 = g2 /. {255, 255, 255, 255} -> {0, 0, 0, 0};
(*Fixing bug with icorrect exporting of Ticks in PDF when Graphics3D \
and 2D Raster are combined*)
axes = First@ImportString[ExportString[axes, "PDF"], "PDF"];
(*Getting explicid ImageSize of graphics imported form PDF*)
imageSize = 
 Last@Transpose[{First@#, Last@#} & /@ 
    Sort /@ Transpose@
      First@Cases[axes, 
        Style[{Line[x_]}, ___, RGBColor[1.`, 0.`, 0.`, 1.`], ___] :> 
         x, Infinity]]
(*combining Graphics3D and Graphics*)
result = Show[axes, Epilog -> Inset[g2, {0, 0}, {0, 0}, imageSize]]
Export["C:\\result.pdf", result]

这是我在笔记本中看到的:

Here is what I see in the Notebook:

这是我在 PDF 中得到的内容:

And here is what I get in the PDF:

这篇关于Mathematica:3D 图形中的光栅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆