Based on Oleksandr's excellent [design idea][1] here is my re-implementation of his package which offers much richer set of shapes. ---------- ## How to install the package ## The most recent version of the package can be installed from GitHub by evaluating the following: (* Load the package code *) package = Import["http://raw.github.com/AlexeyPopkov/PolygonPlotMarkers/master/PolygonPlotMarkers.m", "Text"]; (* Install the package (existing file will be overwritten!) *) Export[FileNameJoin[{$UserBaseDirectory, "Applications", "PolygonPlotMarkers.m"}], package, "Text"]; For manual installation copy the code from the bottom of this post and save as "PolygonPlotMarkers.m" in the directory `SystemOpen[FileNameJoin[{$UserBaseDirectory, "Applications"}]]`. ---------- ## Description of the package ## > - The basic usage syntax is <code>PolygonMarker[*shape*, *size*]</code> where <code>*shape*</code> is a name of built-in shape or a list of 2D coordinates describing a non-selfintersecting polygon. The <code>*size*</code> can be given as a number or in `Scaled` or `Offset` form. > - `PolygonMarker[All]` and `PolygonMarker[]` return the list of names of built-in shapes. > - <code>PolygonMarker[*shape*, *size*]</code> returns `Polygon` graphics primitive which can be used in `Graphics`. > - With `Offset` <code>*size*</code> specification the plot marker has fixed size specified in *printer's points* independent of the size of the plot. > - `PolygonMarker`s with identical <code>*size*</code> specifications have equal areas (not counting the area taken by the **edge** of generated `Polygon`). <code>PolygonMarker[*shape*, *size*]</code> returns shape with area <code>*size*<sup>2</sup></code> in the internal coordinate system of `Graphics`. <code>PolygonMarker[*shape*, Offset\[*size*\]]</code> returns shape with area <code>*size*<sup>2</sup></code> *square printer's points*. > - The centroid of polygon returned by <code>PolygonMarker[*shape*, *size*]</code> is always placed at `{0, 0}` in the internal coordinate system of `Graphics`. > - <code>PolygonMarker[*shape*, *size*, *positions*]</code> where <code>*positions*</code> is a list of 2D coordinates evaluates to <code>Translate[PolygonMarker[*shape*, *size*], *positions*]</code>. It represents a collection of multiple identical copies of the shape with centroids placed at <code>*positions*</code>. ---------- ## Examples of use ## The complete list of built-in named shapes: Needs["PolygonPlotMarkers`"] shapes = PolygonMarker[All] Tooltip[Graphics[{FaceForm[Hue@Random[]], EdgeForm[{Black, Thickness[0.003], JoinForm["Miter"]}], PolygonMarker[#, Scaled[.3]]}, ImageSize -> 30], #] & /@ shapes > {"TripleCross", "Y", "UpTriangle", "UpTriangleTruncated", "DownTriangle", > "DownTriangleTruncated", "LeftTriangle", "LeftTriangleTruncated", "RightTriangle", > "RightTriangleTruncated", "ThreePointedStar", "Cross", "DiagonalCross", "Diamond", > "Square", "FourPointedStar", "DiagonalFourPointedStar", "FivefoldCross", "Pentagon", > "FivePointedStar", "FivePointedStarThick", "SixfoldCross", "Hexagon", "SixPointedStar", > "SixPointedStarSlim", "SevenfoldCross", "SevenPointedStar", "SevenPointedStarNeat", > "SevenPointedStarSlim", "EightfoldCross", "Disk", "H", "I", "N", "Z", "S", "Sl"} > [![all available shapes][2]][2] The third argument of `PolygonMarker` can be used to specify the coordinate(s) where the shape should be placed: Graphics[{FaceForm[], EdgeForm[{Black, AbsoluteThickness[1], JoinForm["Miter"]}], PolygonMarker["Circle", Offset[7], RandomReal[{-1, 1}, {20, 2}]], PolygonMarker["ThreePointedStar", Offset[7], RandomReal[{-1, 1}, {20, 2}]], PolygonMarker["FourPointedStar", Offset[7], RandomReal[{-1, 1}, {20, 2}]], PolygonMarker["FivePointedStar", Offset[7], RandomReal[{-1, 1}, {20, 2}]]}, AspectRatio -> 1/2] > [![plot][3]][3] The package allows to use arbitrary polygon as a plot marker. Here is an auxiliary function which converts simple font glyphs into sets of points which are suitable for `PolygonMarker`: pts[l_String] := First@Cases[ ImportString[ ExportString[Style[l, FontFamily -> "Verdana", FontSize -> 20], "PDF"], "PDF"], c_FilledCurve :> c[[2, 1]], Infinity]; (This conversion is approximate. If precise conversion is needed one can apply one of the methods described in "[How can I adaptively simplify a curved shape?][4]") Here is an example of use: ListPlot[ConstantArray[Range[5], 7] + Range[0, 12, 2], PlotStyle -> Gray, Joined -> True, PlotMarkers -> { Graphics[{FaceForm[LightBlue], EdgeForm[Black], PolygonMarker[pts["U"], Scaled[0.05]]}], Graphics[{FaceForm[LightBlue], EdgeForm[Black], PolygonMarker[pts["S"], Scaled[0.05]]}], Graphics[{FaceForm[Red], EdgeForm[Black], PolygonMarker["FivePointedStar", Scaled[0.05]]}], Graphics[{FaceForm[Yellow], EdgeForm[Black], PolygonMarker["FourPointedStar", Scaled[0.05]]}], Graphics[{FaceForm[Green], EdgeForm[Black], PolygonMarker["DownTriangle", Scaled[0.05]]}], Graphics[{FaceForm[Brown], EdgeForm[Black], PolygonMarker["DiagonalSquare", Scaled[0.05]]}], Graphics[{FaceForm[Blue], EdgeForm[Black], Disk[{0, 0}, Scaled[0.05/Sqrt[π]]]}]}, PlotRange -> {{0, 6}, {0, 18}}] > ![plot][5] Here is an example of a plot where plotting symbols significantly overlap, I use here some of the symbols [recommended][6] by [William Cleveland][7] in his early works: ListPlot[RandomReal[{-1, 1}, {6, 20, 2}], PlotMarkers -> { Graphics[{FaceForm[None], EdgeForm[{Black, Thickness[.008]}], Disk[{0, 0}, Scaled[0.03/Sqrt[π]]]}], Graphics[{FaceForm[None], EdgeForm[{Black, Thickness[.008]}], PolygonMarker["UpTriangle", Scaled[0.03]]}], Graphics[{FaceForm[Black], EdgeForm[None], PolygonMarker["Cross", Scaled[0.03]]}], Graphics[{FaceForm[Black], EdgeForm[None], PolygonMarker[pts["U"], Scaled[0.03]]}], Graphics[{FaceForm[Black], EdgeForm[None], PolygonMarker[pts["S"], Scaled[0.03]]}], Graphics[{FaceForm[Black], EdgeForm[None], PolygonMarker[pts["W"], Scaled[0.03]]}]}, Frame -> True, Axes -> False, PlotRangePadding -> Scaled[.1]] > ![plot][8] Additional examples and explanations can be found in the following answers: - [Perfect vertical alignment of `PointLegend` markers and their labels][9] ---------- ---------- The code of the package ----------------------- BeginPackage["PolygonPlotMarkers`"]; ClearAll[PolygonMarker]; PolygonMarker::usage = "\!\(\*RowBox[{\"PolygonMarker\", \"[\", RowBox[{StyleBox[\"shape\", \"TI\"], \",\", \ StyleBox[\"size\", \"TI\"]}], \"]\"}]\) returns Polygon of \!\(\*StyleBox[\"shape\", \"TI\ \"]\) with centroid at {0,0} and area \!\(\*SuperscriptBox[StyleBox[\"size\", \"TI\"], \ StyleBox[\"2\", \"TR\"]]\)."; SyntaxInformation[PolygonMarker] = {"ArgumentsPattern" -> {_, _., _.}}; Begin["`Private`"]; ClearAll[PolygonArea, PolygonCentroid, LineIntersectionPoint, ngon, nstar, ncross, scale, coords]; (* The shoelace method for computing the area of polygon http://mathematica.stackexchange.com/a/22587/280 *) PolygonArea[pts_?MatrixQ] := Abs@Total[Det /@ Partition[pts, 2, 1, 1]]/2; (* http://mathematica.stackexchange.com/a/7715/280 *) PolygonCentroid[pts_?MatrixQ] := With[{dif = Map[Det, Partition[pts, 2, 1, {1, 1}]]}, ListConvolve[{{1, 1}}, Transpose[pts], {-1, -1}].dif/(3 Total[dif])]; (* http://mathematica.stackexchange.com/a/51399/280 *) LineIntersectionPoint[{a_, b_}, {c_, d_}] := (Det[{a, b}] (c - d) - Det[{c, d}] (a - b))/Det[{a - b, c - d}]; ngon[n_, phase_: 0] := Table[{0, 1}.RotationMatrix[2 k Pi/n + phase], {k, 0, n - 1}]; (* nn - number of vertices in related polygram step - step at which vertices in the polygram are connected n - number of points in the final star an illustration: http://en.wikipedia.org/wiki/Star_polygon#Simple_isotoxal_star_polygons *) nstar[n_ /; n >= 5, phase_: 0] := nstar[n, 2, n, phase]; nstar[nn_, step_, n_, phase_: 0] /; Divisible[nn, n] && nn/2 > step > nn/n := Module[{a1, a2, b1, b2, ab}, {a1, a2, b1, b2} = ngon[nn][[{1, 1 + step, 1 + nn/n, nn/n - step}]]; ab = LineIntersectionPoint[{a1, a2}, {b1, b2}]; Flatten[ Table[{a1, ab}.RotationMatrix[2 k Pi/n + phase], {k, 0, n - 1}], 1]]; (* a - semiwidths of the crossing stripes *) ncross[n_, phase_: 0, a_: 1/10] := Flatten[NestList[#.RotationMatrix[2 Pi/n] &, {{-a, 1}, {a, 1}, {a, a Cot[Pi/n]}}.RotationMatrix[phase], n - 1], 1]; (* Unitizes the area of the polygon *) scale[coords_] := Chop[#/Sqrt@PolygonArea@#] &@N[coords, {18, 18}]; coords["UpTriangle" | "Triangle"] = ngon[3] // scale; coords["DownTriangle"] = ngon[3, Pi/3] // scale; coords["LeftTriangle"] = ngon[3, Pi/6] // scale; coords["RightTriangle"] = ngon[3, -Pi/6] // scale; coords["ThreePointedStar"] = nstar[12, 5, 3] // scale; coords["DiagonalSquare" | "Diamond"] = ngon[4, 0] // scale; coords["Square"] = ngon[4, Pi/4] // scale; coords["FourPointedStar"] = nstar[8, 3, 4] // scale; coords["DiagonalFourPointedStar"] = nstar[8, 3, 4, Pi/4] // scale; coords["Pentagon"] = ngon[5] // scale; coords["FivePointedStar"] = nstar[5] // scale; coords["FivePointedStarThick"] = nstar[20, 7, 5] // scale; coords["Hexagon"] = ngon[6] // scale; coords["SixPointedStar"] = nstar[6] // scale; coords["SixPointedStarSlim"] = nstar[12, 5, 6] // scale; coords["SevenPointedStar"] = nstar[7] // scale; coords["SevenPointedStarNeat"] = nstar[14, 5, 7] // scale; coords["SevenPointedStarSlim"] = nstar[14, 6, 7] // scale; coords["Cross"] = ncross[4] // scale; coords["DiagonalCross"] = ncross[4, Pi/4] // scale; coords["TripleCross" | "TripleCrossUp"] = ncross[3] // scale; coords["TripleCrossDown" | "Y"] = ncross[3, Pi/3] // scale; coords["FivefoldCross"] = ncross[5] // scale; coords["SixfoldCross"] = ncross[6] // scale; coords["SevenfoldCross"] = ncross[7] // scale; coords["EightfoldCross"] = ncross[8] // scale; (* The truncated triangle shape originates from the Cross's Theorem http://demonstrations.wolfram.com/CrosssTheorem/ *) coords["UpTriangleTruncated" | "TriangleTruncated" | "TruncatedTriangle"] = Flatten[{{-3, 6 + Sqrt[3]}, {3, 6 + Sqrt[3]}}.RotationMatrix[# Pi/3] & /@ {0, 2, 4}, 1] // scale; coords["DownTriangleTruncated"] = coords["UpTriangleTruncated"].ReflectionMatrix[{0, 1}]; coords["LeftTriangleTruncated"] = coords["UpTriangleTruncated"].RotationMatrix[Pi/6]; coords["RightTriangleTruncated"] = coords["UpTriangleTruncated"].RotationMatrix[-Pi/6]; (* Circle approximated by 24-gon *) coords["Circle" | "Disk"] = ngon[24] // scale; (* Plotting symbols recommended in [Cleveland W.S. The Elements of Graphing Data (1985)] *) (* Symmetric symbol "H" *) coords["H"] = Join[#, -#] &@Join[#, Reverse@#.{{1, 0}, {0, -1}}] &@{{333, 108}, {333, 630}, {585, 630}} // scale; (* Symmetric symbol "I" *) coords["I"] = Join[#, -#] &@{{-20, -68}, {-64, -68}, {-64, -104}, {64, -104}, {64, -68}, {20, -68}} // scale; (* Antisymmetric symbol "N" *) coords["N"] = Join[#, -#] &@{{18, -32}, {30, -32}, {30, 32}, {17, 32}, {17, -12}} // scale; (* Antisymmetric symbol "Z" *) coords["Z"] = Join[#, -#] &@{{-567, -432}, {-567, -630}, {567, -630}, {567, -414}, {-234, -414}} // scale; (* Antisymmetric symbol "S" (simple) *) coords["S"] = Join[#, -#] &@{{-176, -54}, {116, -54}, {167, -100}, {167, -170}, {116, -216}, {-284, -216}, {-284, -324}, {176, -324}, {293, -216}, {293, -54}} // scale; (* Antisymmetric symbol "S" (curved, long) *) coords["LongS"|"SLong"|"Sl"] = Join[#, -#] &@ {{-49/16, -3/11}, {-425/91, 23/28}, {-141/26, 31/12}, {-165/32, 88/19}, {-167/45, 106/17}, {-24/17, 149/21}, {121/69, 233/33}, {130/27, 31/5}, {130/27, 118/29}, {127/47, 199/39}, {7/20, 233/42}, {-12/7, 139/26}, {-65/21, 139/31}, {-395/113, 114/35}, {-157/52, 77/39}, {-83/44, 56/41}, {9/22, 39/43}} // scale; PolygonMarker[name_String, size_?NumericQ] := Polygon[size coords[name]]; PolygonMarker[name_String, (h : Scaled | Offset)[size_?NumericQ]] := Polygon[h[size #, {0, 0}] & /@ coords[name]]; PolygonMarker[coords : {{_?NumericQ, _?NumericQ} ..}, size_?NumericQ] := Polygon[size N[ scale[Transpose[ Transpose[coords] - PolygonCentroid[coords]]], {16, 16}]]; PolygonMarker[coords : {{_?NumericQ, _?NumericQ} ..}, Scaled[size_?NumericQ]] := Polygon[Scaled[size #, {0, 0}] & /@ N[scale[Transpose[ Transpose[coords] - PolygonCentroid[coords]]], {16, 16}]]; PolygonMarker[arg : _String | {{_?NumericQ, _?NumericQ} ..}, size : _?NumericQ | (Scaled | Offset)[_?NumericQ], positions : {_?NumericQ, _?NumericQ} | {{_?NumericQ, _?NumericQ} ..}] := Translate[PolygonMarker[arg, size], positions]; (* The list of all available shapes *) PolygonMarker[] = PolygonMarker[All] = {"TripleCross", "Y", "UpTriangle", "UpTriangleTruncated", "DownTriangle", "DownTriangleTruncated", "LeftTriangle", "LeftTriangleTruncated", "RightTriangle", "RightTriangleTruncated", "ThreePointedStar", "Cross", "DiagonalCross", "Diamond", "Square", "FourPointedStar", "DiagonalFourPointedStar", "FivefoldCross", "Pentagon", "FivePointedStar", "FivePointedStarThick", "SixfoldCross", "Hexagon", "SixPointedStar", "SixPointedStarSlim", "SevenfoldCross", "SevenPointedStar", "SevenPointedStarNeat", "SevenPointedStarSlim", "EightfoldCross", "Disk", "H", "I", "N", "Z", "S", "Sl"}; (* A subset of plot markers suitable for use when plotting symbols on the plot significantly overlap. *) PolygonMarker["Overlap"] = {"TripleCross", "Y", "UpTriangle", "DownTriangle", "LeftTriangle", "RightTriangle", "ThreePointedStar", "Cross", "DiagonalCross", "Diamond", "Square", "FourPointedStar", "DiagonalFourPointedStar", "FivefoldCross", "FivePointedStar", "FivePointedStarThick", "Disk", "H", "I", "N", "Z", "S", "Sl"}; End[]; EndPackage[]; [1]: http://mathematica.stackexchange.com/a/84858/280 [2]: https://i.sstatic.net/j8uOs.png [3]: https://i.sstatic.net/QGBjB.png [4]: http://mathematica.stackexchange.com/q/137937/280 [5]: https://i.sstatic.net/CFm4o.png [6]: http://graphicdesign.stackexchange.com/q/36908/946 [7]: http://www.stat.purdue.edu/~wsc/ [8]: https://i.sstatic.net/26Ula.png [9]: http://mathematica.stackexchange.com/a/137758/280