9
$\begingroup$

I have a list of 2D points I want to plot with ListPlot. I want the edges connecting these points to have certain colors. So in addition to setting the ListPlot option Joined to True, I will also need to set the Mesh and MeshShading options. As far as I know, the only value for the Mesh option that will put a mesh point at each point I pass to ListPlot is Mesh->Full. However, if I use this value, then the MeshShading option doesn't seem to do anything.

To get a minimum working example, I will just go to the ListPlot documentation and go to Options and then MeshShading in their drill-down menu.

The first example is

ListPlot[Table[Binomial[15, k], {k, 0, 15}], Mesh -> 10, 
 MeshShading -> {Red, Blue}, Joined -> True]

which produces

enter image description here

But, as I explained, I will have to use Mesh->Full, so I make this change to the command to get the following command

ListPlot[Table[Binomial[15, k], {k, 0, 15}], Mesh -> Full, 
 MeshShading -> {Red, Blue}, Joined -> True]

The command produces the following plot:

enter image description here

As you can see, the mesh does not have the specified coloring. My question is, "How do I get ListPlot to use the given value of the MeshShading option when I am also using the option Mesh->Full?"

Notice that I realize

ListPlot[Table[Binomial[15, k], {k, 0, 15}], Mesh -> {Range[16], {}}, 
 MeshShading -> {Red, Blue}, Joined -> True]

(for example), gives me what I want in this case, but in general, I will be plotting an arbitrary list of 2D points, so this will not work.

$\endgroup$
6
  • $\begingroup$ Would the alternative Mesh -> Length[points], where points is your arbitrary list of 2D points, work? More explicitly, once the list points is generated, something like: With[{p = points}, ListPlot[p, Mesh -> Length[p], MeshShading -> {Red, Blue}, Joined -> True]]. $\endgroup$
    – user31159
    Sep 15, 2016 at 18:21
  • $\begingroup$ @Xavier No that creates meshpoints wherever the x coordinate on an edge has one of Length[points] evenly spaced values. Try it. ListPlot[RandomReal[{-1, 1}, {12, 2}], Mesh -> 12, MeshShading -> {Red, Blue}, Joined -> True] $\endgroup$ Sep 15, 2016 at 18:28
  • $\begingroup$ Good point, I just tried it. I can think of a workaround with Show, Graphics (to draw colored lines) and ListPlot (for the points), but this seems a little ugly (and as a workaround, it does not answer your question). $\endgroup$
    – user31159
    Sep 15, 2016 at 18:41
  • $\begingroup$ So why can't you take the x coordinates from your arbitrary list and put them into Mesh? $\endgroup$
    – C. E.
    Sep 15, 2016 at 18:58
  • $\begingroup$ @C. E. I don't understand. You mean like this? data = RandomReal[{-1, 1}, {12, 2}]; ListPlot[data, Mesh -> {data[[;; , 1]], {}}, MeshShading -> {Red, Blue}, Joined -> True] $\endgroup$ Sep 15, 2016 at 19:01

2 Answers 2

3
$\begingroup$

There are a couple of subtleties here that are not captured by your minimal working example but are obvious from the comments discussion: you have a non-uniformly sampled dataset you want to plot as opposed to the uniformly sampled one uniData = Table[Binomial[15, k], {k, 0, 15}]. If you had a uniformly sampled dataset, the solution suggested by @Xavier in the comments Mesh-> Length@uniData is fine as far as I can see.

But a non-uniform dataset, like:

nonuniData = RandomReal[{-1, 1}, {12, 2}];

you want a parameter along the curve as a mesh function and #3 is exaclty that. So

ListLinePlot[nonuniData,
 MeshFunctions -> {-#3 &}, 
 Mesh -> (Length@nonuniData - 1), 
 MeshShading -> {Blue, Red}]

produces the desired (although the first point is missing so you'd have to add this manually).

enter image description here

This doesn't include the option Mesh->Full however.

$\endgroup$
3
  • $\begingroup$ Thanks for this answer it seems useful. Where did you learn about using #3 for MeshFunctions with ListPlot? If you go to the MeshFunctions page and click on details, and go to their fourth bullet point, it says in the first row of the table of this bullet point that ListLinePlot mesh functions are given only two arguments, which are x and y. (I see ParametricPlot gets a third argument though.) Also, can you comment on why the minus sign in front of #3 is necessary? $\endgroup$ Sep 16, 2016 at 14:57
  • $\begingroup$ And as far as the missing point, I am lucky that in my case, the points are supposed to lie on a closed curve, so I am really passing Append[data,First@data] to ListPlot, so all my points will get drawn. Of course, a simple workaround in the original case would be Prepend[data,First@data], and then make sure to change the number of mesh points from Length@data-1 to Length@data to take into account the extra data point you are passing to ListPlot. $\endgroup$ Sep 16, 2016 at 14:59
  • $\begingroup$ I am trying to remember where I first saw that #3 can be used as an argument in MeshFunctions but I can't. It's entirely possible I was stuck with something similar - for the record, I have also used ArcLength as a Mesh function. I didn't know that was an option either... $\endgroup$
    – gpap
    Sep 16, 2016 at 15:04
0
$\begingroup$

Here is a workaround suggested by Xavier in the comments. First make some dummy data:

data = RandomReal[{-1, 1}, {12, 2}];

now make some dummy colors for the data:

colors = Hue /@ (Range@Length@data/Length@data)

then to make my plot, I can do

Show[{
  ListPlot[data],
  Graphics[MapThread[{#3, Line[{#1, #2}]} &,{data,RotateLeft@data,colors}]]
}]

Basically, I am using ListPlot to plot the points, and then just making the lines myself. I would hope there is a better answer though.

$\endgroup$

Your Answer

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

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