Cycle through MeshStyle directives in ListLinePlot

SeedRandom[123]
data = {Table[1/n + RandomReal[{-1, 1}]/n, {n, 1, 20}], Table[1/n, {n, 1, 20}]};

Assuming that you want different mesh styles for points on different lines (with default setting for the option MeshFunctions, that is, {#&}), you can

  1. Combine two separate plots using Show:

Show[MapThread[ListLinePlot[#, Mesh -> All, PlotRange -> All,
   PlotStyle -> #2, MeshStyle -> #3]&, {data, {Red, Blue}, {Yellow, Green}}],
 PlotRange -> All]

enter image description here

  1. Post-process the output of a single ListLinePlot to change the colors of points:

llp = ListLinePlot[data,  Mesh -> All,
     PlotStyle -> {Red, Blue}, MeshStyle -> {Yellow, Green}, PlotRange -> All];
meshstyles = Reverse @ { Yellow, Green};
llp /. p_Point :> {First[meshstyles = RotateRight[meshstyles]], p}

same picture

  1. Use a Dynamic mesh style:

meshstyles = Reverse @ {Yellow, Green};
ListLinePlot[data, Mesh -> All, PlotStyle -> {Red, Blue}, PlotRange -> All,
  MeshStyle -> Dynamic[First[meshstyles = RotateRight[meshstyles]]]]

same picture

  1. Use a function as the MeshStyle setting:

meshstyles = Reverse @ {Yellow, Green};
ListLinePlot[data, Mesh ->All, PlotStyle -> {Red, Blue},PlotRange -> All,
  MeshStyle -> ({First[meshstyles = RotateRight[meshstyles]],
    PointSize[Large], #}&)]

same picture

All the methods above work with arbitrary number of data rows:

n = 10;
meshstyles = Reverse [ ColorData[70] /@ Range[n]];
plotstyles = ColorData[97] /@ Range[n];
SeedRandom[1]
data = MapThread[Plus, {5 + Range[n], (Accumulate /@ RandomReal[{-1, 1}, {n, 15}])}];

ListLinePlot[data, Mesh -> All,  ImageSize -> Large, PlotRange -> All,
 PlotStyle -> plotstyles,
 MeshStyle -> ({First[meshstyles = RotateRight[meshstyles]], PointSize[Large], #} &), 
 PlotLegends -> LineLegend[Automatic, Range[n], LegendMarkers -> 
   (Graphics[{#, PointSize[Large], Point[{0, 0}]}] & /@ Reverse[meshstyles])]]

enter image description here


The problem is that in order for MeshStyle to cycle through the list, you have to have more than one mesh, and this is determined by the number of MeshFunctions you have. By default, this is set to

MeshFunctions -> {#1&}

for ListLinePlot. If you add

MeshFunctions -> {#1 &, #2 &}

to your plot, Yellow will be used for the horizontal mesh, and Green for the vertical mesh, e.g.

SeedRandom[15];
ListLinePlot[{Table[1/n + RandomReal[{-1, 1}]/n, {n, 1, 20}], 
  Table[1/n, {n, 1, 20}]}, Mesh -> {5, 7}, 
 MeshFunctions -> {#1 &, #2 &}, PlotStyle -> {Red, Blue}, 
 MeshStyle -> {Yellow, Green}]

enter image description here

Tags:

Plotting