34
$\begingroup$

Bug introduced in 10.0.0 and fixed in 10.0.1


In Mathematica 10.0.0 we have built-in graphical triangle PlotMarkers. Let us look closer on them:

ListLinePlot[{{Missing[]}, {{0, 0}}}, PlotTheme -> "Monochrome", 
 ImageSize -> 20, Ticks -> False, AxesOrigin -> {0, 0}, 
 BaseStyle -> {Magnification -> 10, Thickness -> Tiny}]

ListLinePlot[{{Missing[]}, {{0, 0}}}, 
 PlotTheme -> {"OpenMarkersThick", "LargeLabels"}, ImageSize -> 20, 
 Ticks -> False, AxesOrigin -> {0, 0}, 
 BaseStyle -> {Magnification -> 10, Thickness -> Tiny}]

plot1

plot2

It is clear that there is something wrong with the triangles. Is this functionality implemented correctly?

$\endgroup$
2
  • $\begingroup$ Based on the large number of upvotes I think that the community has confirmed that the described behavior is a bug in v.10.0.0. So I add appropriate tag. $\endgroup$ Jul 31, 2014 at 16:38
  • 2
    $\begingroup$ Looks OK in 10.0.1. $\endgroup$ Sep 17, 2014 at 13:24

1 Answer 1

37
$\begingroup$

The triangle plot markers

It is natural to expect that the triangle marker is placed in such a way that its center of mass (center of circumcircle) coincides with the point it marks. That's how it is implemented in all major scientific plotting software, for example Origin:

plot markers in Origin 7.5

Some time ago I published my own implementation of triangle-based plot markers. Let us check how the new markers are implemented:

ListLinePlot[{{Missing[]}, {{0, 0}}}, PlotTheme -> "Monochrome", 
 ImageSize -> 10, Ticks -> False, AxesOrigin -> {0, 0}, 
 BaseStyle -> {Magnification -> 10, Thickness -> Tiny}]
%[[1, 2, 2, 2, -1]] // InputForm

screenshot

GeometricTransformation[Inset[Graphics[{<...>
      Line[{Offset[{0., 2.7625}], 
        Offset[{-2.7625, -2.022290355909023}], 
        Offset[{2.7625, -2.022290355909023}], 
        Offset[{0., 2.7625}]}]}], {0., 0.}],
     {{{0., 0.}}, {{0., 0.}}}]

Apart of the fact that the curve is not closed, the triangle is positioned in a strange way: the "center" is placed on the

2.022290355909023/(2.7625 + 2.022290355909023)

0.4226497308103742

part of the height of the triangle instead of expected 1/3 (the center of circumcircle). So current implementation is clearly wrong and leads to producing incorrect plots. Here is an example of correct implementation:

Graphics[{AbsoluteThickness[1], JoinedCurve[
   Line[{Offset[{0, 2}], Offset[{Sqrt[3], -1}], 
     Offset[{-Sqrt[3], -1}]}], CurveClosed -> True]},
 ImageSize -> 10, Axes -> True, Ticks -> False, AxesOrigin -> {0, 0}, 
 BaseStyle -> {Magnification -> 10, Thickness -> Tiny}]

screenshot

The following is correct implementation of both empty and filled triangle plot markers of strictly identical sizes with consistent explicit control over their sizes and thickness:

emptyUpTriangle = 
  Graphics[{AbsoluteThickness[absoluteThickness], 
    JoinedCurve[Line[{Offset[size {0, 2}], Offset[size {Sqrt[3], -1}], 
       Offset[size {-Sqrt[3], -1}]}], CurveClosed -> True]}, 
   AlignmentPoint -> {0, 0}];
filledUpTriangle = 
  Graphics[{Triangle[{Offset[size {0, 2} + absoluteThickness {0, 1}], 
      Offset[size {Sqrt[3], -1} + absoluteThickness {Sqrt[3/4], -1/2}], 
      Offset[size {-Sqrt[3], -1} + absoluteThickness {-Sqrt[3/4], -1/2}]}]}, 
   AlignmentPoint -> {0, 0}];
{emptyLeftTriangle, filledLeftTriangle, emptyDownTriangle, 
   filledDownTriangle, emptyRightTriangle, filledRightTriangle} = 
  Flatten[{emptyUpTriangle, filledUpTriangle} /. {x_?NumericQ, y_?NumericQ} :> 
       RotationTransform[#][{x, y}] & /@ {Pi/2, Pi/3, -Pi/2}];

SeedRandom[12]
ListLinePlot[Accumulate /@ RandomReal[3, {8, 10}] Range[8], 
 PlotMarkers -> {emptyUpTriangle, filledUpTriangle, emptyLeftTriangle,
    filledLeftTriangle, emptyDownTriangle, filledDownTriangle, 
   emptyRightTriangle, filledRightTriangle}, AspectRatio -> 1]

plot

And here is an extended version which includes open triangles with white filling:

size = 4; absoluteThickness = 2;

triangle[Up, Empty] = 
  Graphics[{AbsoluteThickness[absoluteThickness], 
    JoinedCurve[Line[{Offset[size {0, 2}], Offset[size {Sqrt[3], -1}], 
       Offset[size {-Sqrt[3], -1}]}], CurveClosed -> True]}, 
   AlignmentPoint -> {0, 0}];
triangle[Up, Filled] = 
  Graphics[{Triangle[{Offset[size {0, 2} + absoluteThickness {0, 1}], 
      Offset[size {Sqrt[3], -1} + absoluteThickness {Sqrt[3/4], -1/2}], 
      Offset[size {-Sqrt[3], -1} + absoluteThickness {-Sqrt[3/4], -1/2}]}]}, 
   AlignmentPoint -> {0, 0}];
triangle[Up, Open] = 
  Graphics[{{White, Triangle[{Offset[size {0, 2}], Offset[size {Sqrt[3], -1}], 
       Offset[size {-Sqrt[3], -1}]}]}, {AbsoluteThickness[absoluteThickness], 
     JoinedCurve[Line[{Offset[size {0, 2}], Offset[size {Sqrt[3], -1}], 
        Offset[size {-Sqrt[3], -1}]}], CurveClosed -> True]}}, 
   AlignmentPoint -> {0, 0}];
triangle[dir_: {Up, Right, Down, Left}, fill_: {Empty, Filled, Open}] := 
 triangle[Up, fill] /. {x_?NumericQ, y_?NumericQ} :> 
   RotationTransform[dir /. {Right -> -Pi/2, Down -> Pi/3, Left -> Pi/2}][{x, y}]

pl = ListPlot[Flatten[Table[{{n, y}}, {y, Range[2]}, {n, 6}], 1], 
  PlotMarkers -> 
   Flatten@Table[triangle[dir, fill], 
            {dir, {Up, Right, Down, Left}}, {fill, {Empty, Filled, Open}}], 
            GridLines -> {Range[6], Range[2]}, 
  PlotRange -> {{0, 7}, {0, 3}}, Axes -> False, Frame -> True]

plot2


Other plot markers

Not only triangle plot markers have problems:

ListLinePlot[{{#, 0}} & /@ Range[5], PlotTheme -> "Monochrome", 
 ImageSize -> 70, Ticks -> False, Axes -> False, Frame -> True, 
 BaseStyle -> {Magnification -> 15, Thickness -> Tiny}, 
 PlotRange -> {{0.5, 5.5}, All}, AspectRatio -> 1/10, 
 FrameTicks -> None, BaselinePosition -> Center, 
 GridLines -> {Range[5], {0}}, 
 GridLinesStyle -> Directive[{Dashing[None], Gray}], 
 Method -> {"GridLinesInFront" -> True}]
Cases[%, g_Graphics :> 
  Show[g, ImageSize -> 8, BaseStyle -> {Magnification -> 16}, 
   BaselinePosition -> Center], Infinity]
Cases[%[[4]], _Line, Infinity]

screenshot

{Line[{Offset[{-2.5, -2.5}],   Offset[{2.125, -2.125}], 
       Offset[{2.125, 2.125}], Offset[{-2.125, 2.125}], 
       Offset[{-2.125, -2.125}]}]}

As one can see, the square starts from the point {-2.5, -2.5} and ends in {-2.125, -2.125}!

$\endgroup$
3
  • $\begingroup$ Are the other shapes also fixed in 10.0.1? $\endgroup$
    – Guillochon
    Sep 17, 2014 at 19:06
  • $\begingroup$ @Guillochon To my eyes, yes. (10.0.1 under Windows) $\endgroup$
    – Mr.Wizard
    Sep 26, 2014 at 12:03
  • $\begingroup$ All the mentioned bugs are fixed. The only remaining inconsistency I can see is that empty and filled triangles have not exactly equal sizes: Show[%[[2]],%[[5]]/.filled_Polygon:>{Opacity[1/2],Yellow,filled/.{x_?NumericQ,y_?NumericQ}:>RotationTransform[Pi/3][{x,y}]},BaseStyle->Magnification->16]. $\endgroup$ Oct 5, 2014 at 1:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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