Skip to main content

graphics - Plot points shifted (a lot) in output and PNG export but not in PDF export


Bug introduced in 8 or earlier and fixed in 12.0.0





Consider the following code:


Needs["SciDraw`"]
Needs["PolygonPlotMarkers`"]
plotData = {{1, 0}};
markers[size_] := Graphics[{PolygonMarker["Disk", Offset[size]]}];
plotA = ListPlot[plotData, PlotMarkers -> markers[8]];
plot = Figure[FigurePanel[{FigGraphics[plotA]}], CanvasSize -> {3, 2}]

enter image description here



The plotted point is not where it's supposed to be, that is, at {1,0}. In fact, it is shifted by precisely {-0.5,0.5}. Only when exported to pdf (last panel) does the point appear at the right position.


What could be the reason for this behavior?


Note that both SciDraw and PolygonPlotMarkers seem to influence the result. At least I can't reproduce the phenomenon when not using both of those packages. However, independent of what those packages do, what could possibly lead to a different output in these two file formats?


If it matters, I have tested this using version 11.0.1 and version 10.4.1 on 64 bit Linux.


SciDraw is available from here.


PolygonPlotMarkers is available from here.



Answer



This issue has nothing to do with the PolygonPlotMarkers` package and appears with any primitive-based plot marker:


Needs["SciDraw`"]
plotData = {{1, 0}};

plotA = ListPlot[plotData, PlotMarkers -> Graphics[Disk[{0, 0}, Offset[3]]]]
plot = Figure[FigurePanel[{FigGraphics[plotA]}], CanvasSize -> {3, 2}]


output


output



After some digging I distilled the problem to the following:


g[size_] := Graphics[GeometricTransformation[{
Inset[Graphics[{Blue, Disk[{0, 0}, Offset[7]]}], {1, 0}],

Inset[Style["\[FilledCircle]", Red, FontSize -> 15], {1, 0}]},
{{216, 0}, {0, 144}}],
Frame -> True, PlotRange -> {{0, 216}, {0, 144}}, ImageSize -> size];

g /@ {150, 200, 300, 400}


screenshot



Here is how it looks Exported to PDF:



Export["i.pdf", %] // SystemOpen


screenshot



In the above we have the same affine transformation applied to two Insets: the first contains Graphics, the second contains a glyph. Both Insets have identical second arguments which specify where they will be placed in the enclosing graphics, hence one should expect that their positions will be identical as it takes place without applying GeometricTransformation:


Graphics[{
Inset[Graphics[{Blue, Disk[{0, 0}, Offset[7]]}], {1, 0}],
Inset[Style["\[FilledCircle]", Red, FontSize -> 15], {1, 0}]},
Frame -> True, PlotRange -> {{0, 1}, {0, 1}}]



graphics



So we have faced a bug in rendering of GeometricTransformation by the FrontEnd. I have found two workarounds:




  1. Specify explicit AlignmentPoint for Graphics:


    g[size_] := Graphics[GeometricTransformation[{
    Inset[Graphics[{Blue, Disk[{0, 0}, Offset[6]]}, AlignmentPoint -> {0, 0}], {1, 0}],

    Inset[Style["\[FilledCircle]", Red, FontSize -> 15], {1, 0}]},
    {{216, 0}, {0, 144}}],
    Frame -> True, PlotRange -> {{0, 216}, {0, 144}}, ImageSize -> size];

    g /@ {150, 200, 300, 400}


    screenshot






  2. Specify explicit third argument for Inset:


    g[size_] := Graphics[GeometricTransformation[{
    Inset[Graphics[{Blue, Disk[{0, 0}, Offset[6]]}], {1, 0}, {0, 0}],
    Inset[Style["\[FilledCircle]", Red, FontSize -> 15], {1, 0}]},
    {{216, 0}, {0, 144}}],
    Frame -> True, PlotRange -> {{0, 216}, {0, 144}}, ImageSize -> size];

    g /@ {150, 200, 300, 400}



    screenshot





For working with the SciDraw` package the first workaround is appropriate:


Needs["SciDraw`"]
plotData = {{1, 0}};
plotA = ListPlot[plotData,
PlotMarkers -> Graphics[{Blue, Disk[{0, 0}, Offset[5]]}, AlignmentPoint -> {0, 0}]];

plot = Figure[FigurePanel[{FigGraphics[plotA]}], CanvasSize -> {3, 2}]


output



I recommend reporting it to the creator of SciDraw` Mark A. Caprio and to Wolfram tech support. Since the usage of primitive-based plot markers is very common, this problem should be taken quite seriously.




UPDATE


It looks like this bug is strongly related to this, and the same workaround works:


Graphics[{GeometricTransformation[{

Inset[Graphics[{Blue, Disk[{0, 0}, Offset[7]]}], {100, 0}],
Inset[Style["\[FilledCircle]", Red, FontSize -> 15], {100, 0}]},
{{216, 0}, {0, 144}}/100]}, Frame -> True, PlotRange -> {{0, 216}, {0, 144}}]


graphics



(I multiplied the second argument of Inset by 100 and divided the transformation matrix by 100).


Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....