7
$\begingroup$

Here is an example of a ListLinePlot. How can get the text of the PlotLabels option to be the same as the colors automatically assigned to the curves by the PlotTheme option?

num = 10;
data1 = N@Sin@Range[num];
data2 = N@Cos@Range[num];
mark = ToString @@@ {Last@data1, Last@data2};

ListLinePlot[{data1, data2},
 Frame -> True,
 GridLines -> Automatic,
 GridLinesStyle -> Directive[Gray, Dotted],
 PlotRange -> All,
 PlotTheme -> "Web",
 PlotLegends -> Placed[SwatchLegend[mark], {Top, Left}],
 PlotLabels -> mark,
 InterpolationOrder -> 2,
 ImageSize -> Large
 ]

enter image description here

Although the user can do this mannually like this here,

{Style[text1, color1], Style[text2, color2]}

when data set count increases, it becomes increasingly more difficult to give the colors values that the PlotTheme option assigned.

$\endgroup$
1
  • 1
    $\begingroup$ Related: (66923) $\endgroup$
    – Michael E2
    Commented Apr 16, 2017 at 16:18

2 Answers 2

8
$\begingroup$

I am eliminating what I consider extraneous details from your code, but I an generalizing the data to an arbitrary number of curves.

With[{nDiv = 10, nCurv = 3},
  data =
    Table[N @ Sin[u + h], {h, Subdivide[π/2, nCurv - 1]}, {u, Subdivide[2 π, nDiv]}]];

plt = ListLinePlot[data, PlotTheme -> "Web"];

lbls =
  MapThread[Style[Last[#1], #2, 14] &, {data, Cases[plt, RGBColor[__], ∞]}];

ListLinePlot[data,
  PlotTheme -> "Web",
  PlotLabels -> lbls,
  ImageSize -> Large]

plot

Update

The OP expresses worry about the performance cost of evaluating the plot twice. Since the 1st plot is not rendered to the screen, its evaluation is not as expensive as a fully rendered plot. However, if the data sets being plotted are very large, it might be profitable to restrict the 1st evaluation to the 1st three points in each data set. Like so:

With[{dta = Take[#, 3] & /@ data},
  plt = ListLinePlot[dta, PlotTheme -> "Web"]];
$\endgroup$
7
  • $\begingroup$ Great! but ListLinePlot shall be executed twice, I doubt the performace go down. $\endgroup$
    – Jerry
    Commented Apr 16, 2017 at 15:00
  • $\begingroup$ why plt/.{PlotLabels->lbls} doesn't work? $\endgroup$
    – Jerry
    Commented Apr 16, 2017 at 15:05
  • $\begingroup$ @Jerry. Take a look at FullForm[plt]. $\endgroup$
    – m_goldberg
    Commented Apr 16, 2017 at 15:10
  • $\begingroup$ @Jerry. I don't know how to do it without re-evaluating the plot. However, when the plot is not rendered on the screen as in the 1st evaluation, it takes far less time than a rendered plot, so the performance hit is not as severe as you might think. $\endgroup$
    – m_goldberg
    Commented Apr 16, 2017 at 15:20
  • 1
    $\begingroup$ @Jerry You can avoid evaluating the plot twice, which is usually quick for ListLinePlot but not always quick for other plotter, with the following: theme = "Web"; styles = "DefaultPlotStyle" /. (Method /. Charting`ResolvePlotTheme[theme, ListLinePlot]); lbls = MapThread[Style[Last[#1], #2, 14] &, {data, PadRight[{}, {Length@data}, styles]}]; $\endgroup$
    – Michael E2
    Commented Apr 16, 2017 at 16:18
2
$\begingroup$

Very neat, but the proposed code seems to go wrong in Mathematica 12.0 because "Cases" gives a list of colours which is too long. Below an ad hoc solution which works here but I don't know how robust it is:

With[{nDiv = 10, nCurv = 3}, 
  data = Table[
    N@Sin[u + h], {h, Subdivide[π/2, nCurv - 1]}, {u, 
     Subdivide[2 π, nDiv]}]];

plt = ListLinePlot[data, PlotTheme -> "Web"];

lbls = MapThread[
  Style[Last[#1], #2, 14] &, {data, 
   Take[Cases[plt, RGBColor[__], ∞], Length[data]]}]

ListLinePlot[data, PlotTheme -> "Web", PlotLabels -> lbls, 
 ImageSize -> Large]

(Sorry I wanted to post as a comment but do not have permission.)

$\endgroup$

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.