Wolfram mathematica Mathematica:3D图形中的光栅

Wolfram mathematica Mathematica:3D图形中的光栅,wolfram-mathematica,Wolfram Mathematica,有时导出为pdf图像很麻烦。如果正在打印的数据包含多个点,则图形的大小将很大,并且您选择的pdf查看器将花费大部分时间渲染此高质量图像。因此,我们可以将此图像导出为jpeg、png或tiff格式。从某个角度看,这张照片会很好,但放大后看起来会完全失真。对于我们正在绘制的图形,这在某种程度上是好的,但是如果您的图像包含文本,那么该文本将看起来是像素化的 为了更好地利用这两个世界,我们可以将这个图形分为两部分:带标签的轴和3D图片。因此,可以将轴导出为pdf或eps,并将三维图形导出为光栅。我希望我

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

为了更好地利用这两个世界,我们可以将这个图形分为两部分:带标签的轴和3D图片。因此,可以将轴导出为pdf或eps,并将三维图形导出为光栅。我希望我知道以后在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]]

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

Export["Axes.pdf", axes];
Export["Fig.pdf", Rasterize[fig, ImageResolution -> 300]];
您将获得两个pdf文件,您可以在其中进行编辑,并将其合并为pdf或eps。我希望事情能这么简单,但事实并非如此。如果您确实这样做了,您将获得:

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

我之前提到过,我通过我的一个情节成功地做到了这一点。我将清理该文件并更改绘图,以使任何人都可以更容易地访问该文件,以确保这是事实。在任何情况下,有人知道为什么我不能使两个pdf文件大小相同吗?另外,请记住,我们希望为光栅化图形获得一个漂亮的绘图。谢谢您的时间

附言。 作为奖励,我们是否可以避免后期编辑,简单地将mathematica中的两个数字合并?光栅化版本和矢量图形版本


编辑: 感谢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的答案,以获取代码中有用的注释。他设法使它在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}]
Export["C:/Result.pdf", result];
Export["C:/Result.eps", result];
此时,您应该看到:

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

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版本,文件大小为614KB,底部是pdf版本,文件大小为455KB。第二列显示从M8获得的输出。顶部是eps版本,文件大小为643KB,底部是pdf版本,文件大小为463KB

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

只需检查(Mma8):

Mathematica 7.0.1的完整解决方案:修复bug 带有注释的代码:

(*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中得到的信息:


这看起来像是无事生非。正如我所读到的,您想要解决的问题如下:

  • 您希望以矢量格式导出,以便在打印时将最佳分辨率用于字体、线条和图形
  • 在编辑程序中,您不希望被渲染复杂矢量图形的缓慢所困扰
通过导出为.eps并使用嵌入的光栅化预览图像,可以满足这些要求

Export["file.eps","PreviewFormat"->"TIFF"]
这将在许多应用中起作用。不幸的是,微软Word的eps过滤器在过去的四个版本中已经发生了巨大的变化,尽管它曾经在一个较旧的功能中为我工作过,但在W2010中已经不复存在了。我听说它可能在mac版本中工作,但我现在无法检查。

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

以下是问题更新部分的代码:

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]
在这种情况下,我们不需要将字体转换为轮廓

更新 正如对此答案的评论所指出的,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]

在这里,我提出了原始解决方案的另一个版本
gr = Overlay[{axes, 
   Rasterize[fig, Background -> None, 
     ImageResolution -> 300] /. {255, 255, 255, 255} -> {0, 0, 0, 0}}]
Export["Result.pdf", gr]
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, 
   Prolog -> 
    Text[Style["Panel A", Bold, Black, 12], 
     ImageScaled[{0.075, 0.975}]]];
fig = Show[fig, AxesStyle -> Directive[Opacity[0]]];
fig = Magnify[fig, 5];
fig = Rasterize[fig, Background -> None];
axes2D = First@ImportString[ExportString[axes, "PDF"], "PDF"];
fig = fig /. 
   Raster[data_, rectangle_, opts___] :> 
    Raster[data, {Scaled[{0, 0}], Scaled[{1, 1}]}, opts];
fig[[1, 2]] = {Scaled[{0, 0}], Scaled[{1, 1}]}
result = Show[axes2D, fig]
Export["C:/Result.pdf", result];
Export["C:/Result.eps", result];
result = Show[axes2D, 
  Epilog -> Inset[fig, Center, Center, ImageScaled[{1, 1}]]]
Export["C:/Result.pdf", result];
Export["C:/Result.eps", result];
result = Show[axes, 
  Epilog -> Inset[fig, Center, Center, ImageScaled[{1, 1}]]]
Export["C:/Result.pdf", result];
fig[[1, 2]] = {ImageScaled[{0, 0}], ImageScaled[{1, 1}]};
result = Show[axes, Epilog -> First@fig]
Export["C:/Result.pdf", result];
fig = Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 3}, Mesh -> None];

Export["export.eps", fig, "AllowRasterization" -> True, 
  ImageResolution -> 600];
epspdf export.eps
ExportAsSemiRaster[filename_, dpi_, fig_, plotrange_, 
   plotrangepadding_] := (
   range = 
    Show[fig, PlotRange -> plotrange, 
     PlotRangePadding -> plotrangepadding];
   axes = Show[Graphics3D[{}, AbsoluteOptions[range]]];
   noaxes = Show[range, AxesStyle -> Transparent];
   raster = 
    Rasterize[noaxes, Background -> None, ImageResolution -> dpi];
   result = 
    Show[raster, 
     Epilog -> Inset[axes, Center, Center, ImageDimensions[raster]]];
   Export[filename, result];
   );
fig = Graphics3D[{Opacity[0.9], Orange, 
    Polygon[{{0, 0, 0}, {4, 0, 4}, {4, 5, 7}, {0, 5, 5}}], 
    Opacity[0.05], Gray, CuboidBox[{0, 0, 0}, {4, 5, 7}]}, 
   Axes -> True, AxesStyle -> Darker[Orange], 
   AxesLabel -> {"x1", "x2", "x3"}, Boxed -> False, 
   ViewPoint -> {-8.5, -8, 6}];
ExportAsSemiRaster["export.pdf", 600, 
  fig, {{0, 4}, {0, 5}, {0, 7}}, {.0, .0, .0}];
Print[Import["export.pdf"]];