Mathematica:3D图形中的栅格

有时候,导出为PDF格式的图像很麻烦。 如果你正在绘制的数据包含很多点,那么你的数字将会很大,你选择的PDF查看器将花费大部分时间来渲染这个高质量的图像。 因此,我们可以将此图像导出为jpeg,png或tiff。 从某个角度来看,图片会很好,但是当你放大时,它会看起来全是扭曲的。 对于我们正在绘制的图形来说,这在某种程度上没有问题,但如果图像包含文本,则该文本将看起来像素化。

为了试图获得两全其美的好处,我们可以将这个数字分成两部分:带有标签的轴和3D图片。 这些坐标轴因此可以导出为pdf或eps格式,并将3D图形导出为栅格格式。 我希望我知道如何在Mathematica中将这两者结合起来,因此目前我们可以使用Inkscape或Illustrator等矢量图形编辑器来组合这两者。

我设法做到了这一点,我在出版物中做了一个小图,但这促使我在Mathematica中创建例程以自动化这个过程。 这是我到目前为止:

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

我喜欢通过将工作目录设置为笔记本目录来启动笔记本。 由于我希望我的图像具有我指定的大小,因此我将打印样式环境设置为正常工作,请查看以了解更多信息。

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}
 ]

在这里,我们设定了我们想要制作的情节的视图。 现在我们创建我们的情节。

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

在这里输入图像描述

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

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

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

在这里输入图像描述

我将facegrid包括在内,以便我们可以在编辑过程中将图形与轴进行匹配。 现在我们导出这两个图像。

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

您将获得两个pdf文件,您可以编辑它们并将它们合并到一个pdf或eps中。 我希望这很简单,但事实并非如此。 如果你真的这样做,你会得到这个:

在这里输入图像描述

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

我之前提到过,我设法通过我的一块地块获得这个。 我会清理文件并更改图表,以便让任何想看到事实真相的人都能访问它。 在任何情况下,有谁知道为什么我不能让这两个pdf文件是相同的大小? 另外,请记住,我们想获得一个漂亮的栅格化图。 感谢您的时间。

PS。 作为奖励,我们可以避免后期编辑,只需将数学中的两个数字结合起来? 栅格化版本和矢量图形版本。


编辑:

感谢rcollyer对他的评论。 我发布了他评论的结果。

有一点要提到的是,当我们导出轴时,我们需要将Background设置为None以便我们可以获得透明图片。

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

在这里输入图像描述

然后,导出图形会产生所需的效果

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

在这里输入图像描述

这些坐标轴保留了矢量图形的精美组件,而该图现在是我们绘制的栅格化版本。 但主要问题仍然存在。 你如何使这两个数字相匹配?

更新:

我的问题已由Alexey Popkov解答。 我想感谢他花时间研究我的问题。 以下代码是您想要使用前面提到的技术的示例。 请参阅Alexey Popkov的回答,在他的代码中提供有用的评论。 他设法使它在Mathematica 7中工作,它在Mathematica 8中工作得更好。结果如下:

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}]

在这一点上你应该看到这个:

在这里输入图像描述

放大功能可以处理图像的分辨率。 你应该尝试不同的值,看看这是如何改变你的照片。

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文件。 除此之外,现在一切正常。 :)

在这里输入图像描述

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

希望这个对你有帮助。 请检查Alexey的答案以查看代码中的注释,它们将帮助您避免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]

这是我在笔记本上看到的内容:

截图

以下是我在PDF中获得的内容:

截图


只需检查(Mma8):

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];
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}];
g = Show[Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, Mesh -> None, 
    AxesLabel -> {"x", "y", "z"}], Options[G3D]];
axes = Graphics3D[{}, AbsoluteOptions[g]];
fig = Show[g, AxesStyle -> Directive[Opacity[0]], 
   FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}];
Export["c:Axes.pdf", axes, Background -> None];
Export["c:Fig.pdf", Rasterize[fig, ImageResolution -> 300]];
a = Import["c:Axes.pdf"];
b = Import["c:Fig.pdf"];
Export["c:FinalFig.pdf", Show[b, a]]

在这里输入图像描述


在Mathematica 8中,使用新的Overlay函数可以更简单地解决问题。

以下是问题的UPDATE部分的代码:

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]]];

这里是解决方案:

gr = Overlay[{axes, 
   Rasterize[fig, Background -> None, ImageResolution -> 300]}]
Export["Result.pdf", gr]

在这种情况下,我们不需要将字体转换为轮廓。

UPDATE

正如jmlopez在评论中指出的那样,在Mathematica 8.0.1的Mac OS X下,选项Background -> None不能正常工作。 一种解决方法是用透明替换白色不透明点:

gr = Overlay[{axes, 
   Rasterize[fig, Background -> None, 
     ImageResolution -> 300] /. {255, 255, 255, 255} -> {0, 0, 0, 0}}]
Export["Result.pdf", gr]
链接地址: http://www.djcxy.com/p/35557.html

上一篇: Mathematica: Rasters in 3D graphics

下一篇: Importing Google Sketchup models in Mathematica