Based on Oleksandr's excellent [design idea][1] here is my re-implementation of his package which offers a much richer set of shapes. ---------- UPDATE from July 2022 ------ A minor update: now the form <code>PolygonMarker[*shape*, *spec*, *positions*]</code>, where <code>*spec*</code> contains numeric specification for <code>*size*</code>, returns a list of `Polygon` graphics primitives with centroids placed at <code>*positions*</code> (instead of a `Translate` object, as it was earlier). This change makes straightforward producing explicit primitives intended for the `Region`-based functionality. As always, this version has no incompatible changes. Added fouth example under the "Scope" section on the [Documentation page for `PolygonMarker`][2], which uses the `Region`-based functionality for producing a high-quality vector figure. This example is also published in [this][3] post. The [GitHib version][4], the [WFR version][2] and this post are updated. The package code has now been removed from this post due to exceeding the 30,000 character limit per post. ---------- UPDATE from February 2022 ------ New version is [published][2] in the WFR! This version introduces new <code>PolygonMarker[*shape*, {*size*, *angle*}]</code> syntax form, which allows to specify the rotation <code>*angle*</code> for the <code>*shape*</code>. Added new built-in shapes: `"DancingStar"`, `"DancingStarRight"`, `"DancingStarThick"`, `"DancingStarThickRight"`, `"FivePointedStarSlim"`, `"SixfoldPinwheel"`, `"SixfoldPinwheelRight"`, `"SevenfoldPinwheel"`, `"SevenfoldPinwheelRight"`. As always, this version has no incompatible changes. ---------- UPDATE from July 2021 ------ New version came out! Now it allows direct generation of `Graphics` objects that can be immediately used as markers for `PlotMarkers`. The new version contains no incompatible changes. The [Wolfram Function Repository version][2] is also updated, but now it differs from the version published here and [on GitHub][4] in the sense that it does not include the general-purpose functions used to generate the built-in shapes on the fly at the package loading time. It was a decision made by the reviewer to define them simply as lists of points, probably for better performance. The functionality and syntax are the same. ---------- UPDATE from October 2019 ------ Now my function is [published][2] in the [Wolfram Function Repository][5] what means that it is available for users of *Mathematica* version 12.0 or higher as `ResourceFunction["PolygonMarker"]`. Users of previous versions should install the package as described below (the functionality is the same). ---------- ## 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 GitHub][6], and save it as "PolygonPlotMarkers.m" in the directory `SystemOpen[FileNameJoin[{$UserBaseDirectory, "Applications"}]]`. ---------- ## Description of the package ## > - The basic usage syntax is <code>PolygonMarker[*shape*, *spec*]</code> where <code>*shape*</code> is a name of built-in shape or a list of 2D coordinates describing a non-selfintersecting polygon, and <code>*spec*</code> can be either <code>*size*</code> or <code>{*size*, *angle*}</code>. > > - The <code>*size*</code> can be given as a number or in `Scaled` or `Offset` form. > > - The <code>*angle*</code> in radians determines the angle of counterclocwise rotation of shape about its centroid. > > - `PolygonMarker[All]` and `PolygonMarker[]` return the list of names of built-in shapes. > > - <code>PolygonMarker[*shape*, *spec*]</code> returns `Polygon` graphics primitive which can be used in `Graphics`. > > - <code>PolygonMarker[*shape*, *size*, *style*]</code>, where <code>*style*</code> is a list of graphics directives applied to <code>*shape*</code>, returns a `Graphics` object which can be used as a marker for `PlotMarkers`. > > - <code>PolygonMarker[*shape*, *size*, *style*, *options*]</code> returns a `Graphics` object with <code>*options*</code> applied. > > - 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*, *spec*, *positions*]</code> where <code>*positions*</code> is a list of 2D coordinates evaluates and <code>*spec*</code> contains numeric specification for <code>*size*</code>, returns a list of `Polygon` graphics primitives with centroids placed at <code>*positions*</code>. > > - <code>PolygonMarker[*shape*, *spec*, *positions*]</code> where <code>*positions*</code> is a list of 2D coordinates and <code>*spec*</code> contains `Scaled` or `Offset` specification for <code>*size*</code>, 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>. ---------- ## Basic examples of use ## The complete list of built-in named shapes: Needs["PolygonPlotMarkers`"] allShapes = PolygonMarker[All] Tooltip[PolygonMarker[#, 1, {FaceForm[Hue@Random[]], EdgeForm[{Black, AbsoluteThickness[0.5], JoinForm["Miter"]}]}, {ImageSize -> 30, PlotRange -> 1.5, PlotRangePadding -> 0, ImagePadding -> 0}], #] & /@ allShapes > {"TripleCross", "Y", "UpTriangle", "UpTriangleTruncated", > "DownTriangle", "DownTriangleTruncated", "LeftTriangle", > "LeftTriangleTruncated", "RightTriangle", "RightTriangleTruncated", > "ThreePointedStar", "Cross", "DiagonalCross", "Diamond", "Square", > "FourPointedStar", "DiagonalFourPointedStar", "FivefoldCross", > "Pentagon", "FivePointedStar", "FivePointedStarSlim", > "FivePointedStarThick", "DancingStar", "DancingStarRight", > "DancingStarThick", "DancingStarThickRight", "SixfoldCross", > "Hexagon", "SixPointedStar", "SixPointedStarSlim", "SixfoldPinwheel", > "SixfoldPinwheelRight", "SevenfoldCross", "SevenPointedStar", > "SevenPointedStarNeat", "SevenPointedStarSlim", "SevenfoldPinwheel", > "SevenfoldPinwheelRight", "EightfoldCross", "Disk", "H", "I", "N", > "Z", "S", "Sw", "Sl"} [![all available shapes][7]][7] Automatic plot legends (*Mathematica* 10 or higher) often require a larger value for the `LegendMarkerSize` option in order to avoid cropping. Filled markers which pick up `PlotStyle` and `PlotTheme` automatically: fm[name_String, size_ : 8] := PolygonMarker[name, Offset[size], EdgeForm[]]; SeedRandom[25]; ListPlot[Table[Accumulate@RandomReal[1, 10] + i, {i, 6}], PlotMarkers -> fm /@ {"Triangle", "Y", "Diamond", "ThreePointedStar", "FivePointedStar", "TripleCross"}, PlotStyle -> ColorData[54, "ColorList"], Joined -> True, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {50, 37}, LegendLayout -> (Column[Row /@ #, Spacings -> -1] &)], ImageSize -> 450] > [![output][8]][8] Empty markers which pick up `PlotStyle` and `PlotTheme` automatically: em[name_String, size_ : 7] := PolygonMarker[name, Offset[size], {Dynamic@EdgeForm@Directive[CurrentValue["Color"], JoinForm["Round"], AbsoluteThickness[2], Opacity[1]], FaceForm[White]}, ImagePadding -> 6]; SeedRandom[2]; ListPlot[Table[Accumulate@RandomReal[1, 10] + i, {i, 3}], PlotMarkers -> em /@ {"Triangle", "Square", "Diamond"}, Joined -> True, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {40, 25}], ImageSize -> 450] SeedRandom[3]; ListPlot[Table[Accumulate@RandomReal[1, 10] + i, {i, 3}], PlotMarkers -> em /@ {"Triangle", "Square", "Diamond"}, Joined -> True, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {40, 25}], PlotTheme -> "Marketing", ImageSize -> 450] > [![output][9]][9] > [![output][10]][10] Filled markers with lighter filling colors: fm2[name_String, size_ : 9] := PolygonMarker[name, Offset@size, { Dynamic@EdgeForm[{CurrentValue["Color"], Opacity[1]}], Dynamic@FaceForm@Lighter[CurrentValue["Color"], 0.75]}]; data = Table[{x, BesselJ[k, x]}, {k, 0, 2}, {x, 0, 10, 0.5}]; ListPlot[data, PlotMarkers -> fm2 /@ {"UpTriangle", "Square", "Circle"}, Joined -> True, Frame -> True, Axes -> False, ImageSize -> 450, PlotRangePadding -> {Scaled[.05], Scaled[.1]}] > [![output][11]][11] ## Advanced usage ## The third argument of `PolygonMarker` can be used to specify the coordinate(s) where the shape should be placed: Graphics[{FaceForm[],EdgeForm[{AbsoluteThickness[1],JoinForm["Miter"]}], EdgeForm[Blue],PolygonMarker["Circle",Offset[7],RandomReal[{-1,1},{20,2}]], EdgeForm[Red],PolygonMarker["ThreePointedStar",Offset[7],RandomReal[{-1,1},{20,2}]], EdgeForm[Darker@Green],PolygonMarker["FourPointedStar",Offset[7],RandomReal[{-1,1},{20,2}]], EdgeForm[Darker@Yellow],PolygonMarker["FivePointedStar",Offset[7],RandomReal[{-1,1},{20,2}]]}, AspectRatio->1/2,ImageSize->450,Frame->True] > [![output][12]][12] Construct a list plot directly from graphics primitives: data = Table[{x, BesselJ[k, x]}, {k, 0, 3}, {x, 0, 10, 0.5}]; markers = {"Circle", "ThreePointedStar", "FourPointedStar", "FivePointedStar"}; colors = {Blue, Red, Darker@Green, Darker@Yellow}; Graphics[Table[{colors[[i]], Line[data[[i]]], FaceForm[White], EdgeForm[{colors[[i]], AbsoluteThickness[1], JoinForm["Miter"]}], PolygonMarker[markers[[i]], Offset[7], data[[i]]]}, {i, Length[data]}], AspectRatio -> 1/2, ImageSize -> 450, Frame -> True] > [![output][13]][13] Construct a custom list plot where open plot markers have transparent faces for each other (but not for the lines): data = Table[{x, BesselJ[k, x]}, {k, 0, 4}, {x, 0, 10, 0.5}]; markers = {"Circle", "ThreePointedStar", "FourPointedStar", "DiagonalFourPointedStar", "FivePointedStar"}; colors = {Blue, Red, Green, Yellow, Orange}; background = Darker@Gray; Graphics[{Table[{colors[[i]], AbsoluteThickness[1.5], Line[data[[i]]], FaceForm[background], EdgeForm[None], PolygonMarker[markers[[i]], Offset[7], data[[i]]]}, {i, Length[data]}], Table[{FaceForm[None], EdgeForm[{colors[[i]], AbsoluteThickness[1.5], JoinForm["Miter"]}], PolygonMarker[markers[[i]], Offset[7], data[[i]]]}, {i, Length[data]}]}, AspectRatio -> 1/2, ImageSize -> 500, Frame -> True, Background -> background, FrameStyle -> White, ImagePadding -> {{30, 20}, {25, 20}}] > [![output][14]][14] Neat Examples ------------- Center markers which pick up `PlotStyle` and `PlotTheme` automatically: cfm[name_String, size_ : 9] := Show[ PolygonMarker[name, Offset@size, {FaceForm[White], Dynamic@EdgeForm[{CurrentValue["Color"], AbsoluteThickness[1], Opacity[1]}]}], PolygonMarker[name, Offset[size/2], EdgeForm[None]]]; data = Table[{x, BesselJ[k, x]}, {k, 0, 2}, {x, 0, 10, 0.5}]; ListPlot[data, PlotMarkers -> cfm /@ {"UpTriangle", "Square", "Circle"}, Joined -> True, Frame -> True, Axes -> False, ImageSize -> 450, PlotRangePadding -> {Scaled[.05], Scaled[.1]}, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {40, 30}], ImageSize -> 450] > [![output][15]][15] Half filled markers which pick up `PlotStyle` and `PlotTheme` automatically: hfm1[name_String, size_ : 9] := Show[ PolygonMarker[name, Offset@size, {FaceForm[White], Dynamic@EdgeForm[{CurrentValue["Color"], AbsoluteThickness[1], Opacity[1]}]}], PolygonMarker[name, Offset@size, EdgeForm[None]] /. {x_?Negative, y_?NumericQ} :> {0, y}]; data = Table[{x, BesselJ[k, x]}, {k, 0, 2}, {x, 0, 10, 0.5}]; ListPlot[data, PlotMarkers -> hfm1 /@ {"UpTriangle", "Square", "Circle"}, Joined -> True, Frame -> True, Axes -> False, ImageSize -> 450, PlotRangePadding -> {Scaled[.05], Scaled[.1]}, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {40, 30}], ImageSize -> 450] > [![output][16]][16] hfm2[name_String, size_ : 9] := Show[ PolygonMarker[name, Offset@size, { FaceForm[White], Dynamic@EdgeForm[{CurrentValue["Color"], AbsoluteThickness[1], Opacity[1]}]}], Graphics[{EdgeForm[None], Replace[RegionDifference[PolygonMarker[name], Rectangle[{-10, -10}, {10, 0}]], p : {x_, y_} :> Offset[size p, {0, 0}], {-2}]}]]; data = Table[{x, BesselJ[k, x]}, {k, 0, 3}, {x, 0, 10, 0.5}]; ListPlot[data, PlotMarkers -> hfm2 /@ {"Diamond", "Square", "Circle", "RightTriangle"}, Joined -> True, Frame -> True, Axes -> False, ImageSize -> 450, PlotRangePadding -> {Scaled[.05], Scaled[.1]}, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {40, 30}], ImageSize -> 450] > [![output][17]][17] Contrast markers which pick up `PlotStyle` and `PlotTheme` automatically: cfm2[name_String, size_ : 9] := Show[ PolygonMarker[name, Offset@size, { FaceForm[White], Dynamic@EdgeForm[{CurrentValue["Color"], AbsoluteThickness[1], Opacity[1]}]}], Graphics[{EdgeForm[None], Replace[RegionDifference[ RegionDifference[PolygonMarker[name], Triangle[{{-10, 10}, {10, 10}, {0, 0}}]], Triangle[{{-10, -10}, {10, -10}, {0, 0}}]], p : {x_, y_} :> Offset[size p, {0, 0}], {-2}]}]]; data = Table[{x, BesselJ[k, x]}, {k, 0, 3}, {x, 0, 10, 0.5}]; ListPlot[data, PlotMarkers -> cfm2 /@ {"Diamond", "Square", "Circle", "DiagonalFourPointedStar"}, Joined -> True, Frame -> True, Axes -> False, ImageSize -> 450, PlotRangePadding -> {Scaled[.05], Scaled[.1]}, PlotLegends -> PointLegend[Automatic, LegendMarkerSize -> {40, 30}], ImageSize -> 450] > [![output][18]][18] The package allows the usage of an arbitrary polygon as a plot marker. Here is an auxiliary function that converts a simple glyph into a set of points suitable for `PolygonMarker`: pts[l_String] := First[Cases[ ImportString[ ExportString[Style[l, FontFamily -> "Verdana", FontSize -> 20], "PDF"], If[$VersionNumber >= 12.2, {"PDF", "PageGraphics"}, {"PDF", "Pages"}]], c_FilledCurve :> c[[2, 1]], Infinity]]; (This conversion is approximate. If the precise conversion is needed one can apply one of the methods described in "[How can I adaptively simplify a curved shape?][19]") An example of use: ListPlot[ConstantArray[Range[5],7]+Range[0,12,2],PlotStyle->Gray,Joined->True,PlotMarkers->{PolygonMarker[pts["U"],Scaled[0.05],{FaceForm[LightBlue],EdgeForm[Black]}], PolygonMarker[pts["S"],Scaled[0.05],{FaceForm[LightBlue],EdgeForm[Black]}], PolygonMarker["FivePointedStar",Scaled[0.05],{FaceForm[Red],EdgeForm[Black]}], PolygonMarker["FourPointedStar",Scaled[0.05],{FaceForm[Yellow],EdgeForm[Black]}], PolygonMarker["DownTriangle",Scaled[0.05],{FaceForm[Green],EdgeForm[Black]}], PolygonMarker["DiagonalSquare",Scaled[0.05],{FaceForm[Brown],EdgeForm[Black]}], Graphics[{FaceForm[Blue],EdgeForm[Black],Disk[{0,0},Scaled[0.05/Sqrt[\[Pi]]]]}]},PlotRange->{{0,6},{0,18}},ImageSize->450] > [![output][20]][20] Here is an example of a black-and-white plot where the markers overlap considerably, I use here some of the symbols [recommended][21] by [William Cleveland][22] in his early works: SeedRandom[11]; ListPlot[RandomReal[{-1,1},{6,20,2}],PlotMarkers->{ PolygonMarker["Circle",Scaled[0.03],{FaceForm[None],EdgeForm[{Black,Thickness[.008]}]}], PolygonMarker["UpTriangle",Scaled[0.03],{FaceForm[None],EdgeForm[{Black,Thickness[.008]}]}], PolygonMarker["Cross",Scaled[0.03],{FaceForm[Black],EdgeForm[None]}], PolygonMarker[pts["U"],Scaled[0.03],{FaceForm[Black],EdgeForm[None]}], PolygonMarker["Sl",Scaled[0.03],{FaceForm[Black],EdgeForm[None]}], PolygonMarker[pts["W"],Scaled[0.03],{FaceForm[Black],EdgeForm[None]}]}, Frame->True,FrameStyle->Black,Axes->False,PlotRangePadding->Scaled[.1],ImageSize->450] > [![output][23]][23] Additional examples and explanations can be found in the following answers: - [How to make transparent markers without plotted lines going through them?][3] - [Plot markers where the boundary has the same hue as the body but is darker][24] - [Perfect vertical alignment of `PointLegend` markers and their labels][25] - [Making antisymmetric curvilinear marker "S"][26] - [How to specify `PlotMarkers` that scale when graphic is resized?][27] - [Bug in `Export` of figures with `PlotMarkers`?][28] [1]: https://mathematica.stackexchange.com/a/84858/280 [2]: https://resources.wolframcloud.com/FunctionRepository/resources/PolygonMarker [3]: https://mathematica.stackexchange.com/a/270194/280 [4]: https://github.com/AlexeyPopkov/PolygonPlotMarkers [5]: https://resources.wolframcloud.com/FunctionRepository/ [6]: https://raw.githubusercontent.com/AlexeyPopkov/PolygonPlotMarkers/master/PolygonPlotMarkers.m [7]: https://i.sstatic.net/pys3G.png [8]: https://i.sstatic.net/jkjBK.png [9]: https://i.sstatic.net/Y01su.png [10]: https://i.sstatic.net/YMDTA.png [11]: https://i.sstatic.net/ZzcS8.png [12]: https://i.sstatic.net/P8MQc.png [13]: https://i.sstatic.net/1QaoH.png [14]: https://i.sstatic.net/3j5Qj.png [15]: https://i.sstatic.net/DG5bU.png [16]: https://i.sstatic.net/XC3so.png [17]: https://i.sstatic.net/71yxC.png [18]: https://i.sstatic.net/x1cI8.png [19]: https://mathematica.stackexchange.com/q/137937/280 [20]: https://i.sstatic.net/1HaZ9.png [21]: https://graphicdesign.stackexchange.com/q/36908/946 [22]: http://www.stat.purdue.edu/~wsc/ [23]: https://i.sstatic.net/AKfl5.png [24]: https://mathematica.stackexchange.com/a/158221/280 [25]: https://mathematica.stackexchange.com/a/137758/280 [26]: https://mathematica.stackexchange.com/a/138348/280 [27]: https://mathematica.stackexchange.com/a/145891/280 [28]: https://mathematica.stackexchange.com/a/250857/280