3
$\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?

New contributor
pedroos is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
$\endgroup$
  • 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 at 21:12
2
$\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$
  • $\begingroup$ Or Show[ Plot[First@fns, {x, -1, 1}, PlotStyle -> Red], Plot[Rest@fns, {x, -1, 1}, PlotStyle -> Black]] $\endgroup$ – Bob Hanlon Jan 13 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 at 0:14
  • $\begingroup$ @MichaelE2 - or the PlotRange can be specified as an option to Show $\endgroup$ – Bob Hanlon Jan 14 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 at 0:18
1
$\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

pedroos is a new contributor. Be nice, and check out our Code of Conduct.

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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