4
$\begingroup$

I'm trying to plot a Table of functions. Since the number of elements is unspecified, I want to specify a "repeating" graphic directive.

Supposing I have two direcives, m and s, I would like to do something like:

PlotStyle -> {m, s...}

But I can only specify

PlotStyle -> {m, s}

However, since this specification is cyclical, I get (what would be like)

{m, s, m, s, m, s...}

So I'm forced to specify

PlotStyle -> {m, s, s, s, s, s, s, s, s, s, s, s}

for the exact number of elements in the Table, and breaking the graphical presentation for another number of elements.

Is there a way I can specify a directive for a number n of first elements in the Table, and another for the remaining elements?

$\endgroup$
1
  • 1
    $\begingroup$ One way to at least make the solution you have more manageable (ie, less code) would be something like PlotStyle -> Flatten[{m, Table[s, 10]} where 10 is the number of elements. $\endgroup$
    – Carl Lange
    Jan 13, 2019 at 21:12

2 Answers 2

3
$\begingroup$

My usual approach would be to programmatically generate the set of styles:

fns = x^Range[5];

Plot[fns, {x, -1, 1}, PlotStyle -> Prepend[Table[Black, 4], Red]]

You could also use Style to override the setting coming from PlotStyle:

Plot[Evaluate[MapAt[Style[#, Red] &, fns, 1]], {x, -1, 1}, 
 PlotStyle -> Black]

enter image description here

$\endgroup$
5
  • $\begingroup$ Or Show[ Plot[First@fns, {x, -1, 1}, PlotStyle -> Red], Plot[Rest@fns, {x, -1, 1}, PlotStyle -> Black]] $\endgroup$
    – Bob Hanlon
    Jan 13, 2019 at 23:17
  • $\begingroup$ @BobHanlon That's a good way, except that the PlotRange will be determined by the first function. Adding PlotRange -> All may help, but not if a function has a very large range compared to others. $\endgroup$
    – Michael E2
    Jan 14, 2019 at 0:14
  • $\begingroup$ @MichaelE2 - or the PlotRange can be specified as an option to Show $\endgroup$
    – Bob Hanlon
    Jan 14, 2019 at 0:16
  • $\begingroup$ @BobHanlon Yeah, I meant adding PlotRange -> All to Show[] but didn't say where it was to go. $\endgroup$
    – Michael E2
    Jan 14, 2019 at 0:18
  • 1
    $\begingroup$ One could also use PadRight[]: Plot[x^Range[5] // Evaluate, {x, -1, 1}, PlotStyle -> PadRight[{Red}, 5, Black]] $\endgroup$ Mar 29, 2019 at 15:04
3
$\begingroup$

Here's a way with an UpValue:

repPlotStyle /: Plot[f_, {x_, a_, b_}, o1___,
   repPlotStyle[PlotStyle -> {s1 : Except[_List] ..., s2_List}],
   o2___] :=
  With[{n = Length[Block[{x = (a + b)/2.}, f]]},  (* could use Length[f] *)
   With[{s = Take[
        Join[{s1}, Apply[Join, Table[s2, {(n/ Length[s2]) + 1}]]],
        n]},
    Plot[f, {x, a, b}, o1, PlotStyle -> s, o2]
    ]];

Plot[Evaluate[ChebyshevT[Range@11, x]], {x, -1, 1},
 PlotStyle -> {Red, {Black}} // repPlotStyle]

enter image description here

Plot[Evaluate[ChebyshevT[Range@11, x]], {x, -1, 1},
 PlotStyle -> {Red, Orange, {Black, Blue, Green}} // repPlotStyle]

enter image description here

Or tweak an internal function in the same way (not guaranteed to work in versions other than 11.3):

Internal`InheritedBlock[
 {Charting`padList},
 Unprotect@Charting`padList;
 Charting`padList[{a_, b_List}, n_Integer] := Take[
    Prepend[Apply[Join, Table[b, {(n/ Length[b]) + 1}]], a],
    n];
 Protect@Charting`padList;
 Plot[Evaluate[ChebyshevT[Range@5, x]], {x, -1, 1},
  PlotStyle -> {Red, {Black}}]
 ]
(* same output as the first graphics *)
$\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.