5
$\begingroup$

This is a followup to:

Carl Woll gave a great answer there: change the "Graphics" style of the current notebook's stylesheet. This is simple to do and indeed affects the style in all GraphicsBoxes.

Unfortunately, the style change does not stick when we export a legended figure to PDF.

Question: How can we work around this problem and preserve the new style even when exporting to PDF?


Demonstration:

We set the "Graphics" style for all style environments:

SetOptions[EvaluationNotebook[],
 StyleDefinitions -> Notebook[{
    Cell[StyleData[StyleDefinitions -> "Default.nb"]], 
    Cell[StyleData["Graphics", All], FontFamily -> "Times"]
    },
   StyleDefinitions -> "PrivateStylesheetFormatting.nb"]
 ]

Additionally, we change the printing style environment to "Working". Otherwise Export would use the "Printout" environment for labelled plots, which would downscale everything.

SetOptions[$FrontEndSession, PrintingStyleEnvironment -> "Working"]

Let's try exporting these two plots:

plot1 = DensityPlot[x, {x, -1, 1}, {y, -1, 1}, PlotLabel -> "Plot 1"]
plot2 = DensityPlot[x, {x, -1, 1}, {y, -1, 1}, PlotLabel -> "Plot 2", PlotLegends -> Automatic]

Both use the Times font when displayed in the notebook, but plot2 will revert to the default font when exported to PDF:

enter image description here

enter image description here


Note: To be more precise, the problem appears when we export something that is not represented as a GraphicsBox. This is the case with Legended expressions when the legend is placed outside of the plot frame. Row[{plot1}] also doesn't export correctly.

$\endgroup$
5
$\begingroup$

I've reported this issue to the import/export team. One possible workaround is to use export on a notebook object representation of the graphics object. For example:

pdfExport[file_, expr_] := Module[{nb},
    Internal`WithLocalSettings[
        nb = CreateDocument[expr, Visible->False, Options[EvaluationNotebook[], StyleDefinitions]],
        Export[file, nb],
        NotebookClose[nb]
    ]
]

Your examples:

pdfExport["plot1.pdf", plot1];
pdfExport["plot2.pdf", plot2];
pdfExport["rowplot.pdf", Row[{plot1}]];

look correct to me. Another workaround is to modify an internal symbol, I can provide this if the above approach proves unsuitable.

(Internal symbol redefinition)

For completeness, here is the workaround where I modify an internal symbol:

DownValues[System`ConvertersDump`createVectorExportPacketExpr] = ReplaceAll[
    DownValues[System`ConvertersDump`createVectorExportPacketExpr],
    Notebook[a__] :> Notebook[a, Options[EvaluationNotebook[], StyleDefinitions]]
];

It is also possible to modify the first DownValue of System`ConvertersDump`createVectorExportPacketExpr, but I think this version is better.

$\endgroup$
  • $\begingroup$ Actually, this seems to export at A4 size. I would be very much interested in a solution which allows me to export to specific sizes. For example, the following sets the graphics box size to be 8 cm wide, while allowing the legend to take up as much space as necessary. It also sets the tickmark font size to 8pt. Plot[{Sin[x], Cos[x]}, {x, 0, 10}, ImageSize -> 8*72/2.54, PlotLegends -> "Expressions", TicksStyle -> Directive[FontSize -> 8]] I would like to preserve these measurements while exporting to PDF. The page size should match the content, and not be A4 size. $\endgroup$ – Szabolcs Jan 12 '18 at 15:44
  • $\begingroup$ Sorry, just to clarify: if I set the printing style environment to Working, then Export already does that. The comment should have been: how to produce the same PDF page size as Export while still fixing the issue asked about in the main question? $\endgroup$ – Szabolcs Jan 12 '18 at 16:49
  • $\begingroup$ Hi Carl, do you have any tips on how to preserve the page size while still fixing the issue in the above question? Perhaps you have a patch for the built-ins (I think you mentioned something like that, but I'm not sure)? $\endgroup$ – Szabolcs Jan 26 '18 at 15:29
  • $\begingroup$ @Szabolcs I'm not sure what goes wrong with the page size. If you want to try modifying an internal function, you can do: DownValues[SystemConvertersDumpcreateVectorExportPacketExpr] = DownValues[ SystemConvertersDumpcreateVectorExportPacketExpr] /. {Graphics, a__} -> {Legended, Graphics, a}. Then, just use Export as usual, not pdfExport. $\endgroup$ – Carl Woll Jan 27 '18 at 6:45
  • $\begingroup$ @Szabolcs Sorry about the messed up ticks. I provided a better workaround in my answer. $\endgroup$ – Carl Woll Jan 27 '18 at 7:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.