6

I'm looking for a way to create a variable that I can use to hold all of the graphics directives for, say, a plot command. For example, I have 8 plots with variations on the following:

Plot[{Im[eppar[400*10^12, t, 0.1]],
      Im[eppar[400*10^12, t, 0.2]], 
      Im[eppar[400*10^12, t, 0.5]], 
      Im[eppar[400*10^12, t, 0.8]]
     }, {t, tlow, thigh}, (**directives**)]

There's a fairly long list of directives I'm using for the plots, and I'd like to avoid having to modify 8 long, complicated expressions every time I want to change anything. Does anybody know of a solution to this? It would make my code much cleaner.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Scott
  • 217
  • 1
  • 4
  • You can use With like in here. – Kuba Jul 30 '13 at 17:33
  • Can you give us a clearer idea what you have in mind when you say "avoid having to modify 8 long, complicated expressions every time I want to change anything"? And I think we would like to see the "8 long, complicated expressions" and definition or eppar so we can work with your code. – m_goldberg Jul 30 '13 at 17:59
  • I think you may simply be looking for Directive. – C. E. Jul 30 '13 at 18:22
  • Closely related: (20718) (setSpec in my second answer is directly applicable.) – Mr.Wizard Jul 30 '13 at 20:12
  • 1
    @Mr.Wizard Guys, this is not a duplicate of that question (somehow my comment was deleted). That question was about how options are passed to HoldAll functions, but the question asked here is not about that technicality. It is much closer (may be a dupe) to this one. I hope I won't have to repeat this comment a third time (i.e this one won't get deleted). – Leonid Shifrin Jul 30 '13 at 21:35
  • @Leonid your comment was deleted by Community♦ probably when the question was closed because it contained the word "duplicate." That seems overly aggressive to me. – Mr.Wizard Jul 30 '13 at 21:38
  • @Leonid I don't know if I agree with you. I also linked 20718 which includes an UpValues method that might be closer to this question. Your answer/proposed duplicate looks a lot more heavy duty than what this question calls for. – Mr.Wizard Jul 30 '13 at 21:41
  • @Mr.Wizard I disagree. I think that the essence of the question is exactly what was discussed in the question I linked, namely, how to create persistent option configurations where several options are set to certain values. The fact that the function is queston happens to be Plot and therefore option-passing has additional subtleties, seems of a secondary importance to me, given the exact wording of the question. – Leonid Shifrin Jul 30 '13 at 21:44
  • @Leonid Do you think this question should be reopened, or closed as a duplicate of (22697)? – Mr.Wizard Jul 30 '13 at 22:18
  • @Mr.Wizard I don't know. This one looks pretty close to that one, so we might as well close as a dupe of that one, but I wouldn't insist on closing. But the one currently marked as the master question for this one, is not it - that's where I have a strong opinion. – Leonid Shifrin Jul 30 '13 at 23:10
  • Maybe I'm misunderstanding something, but why not just use SetOptions[Plot, Filling -> {1 -> {2}}, PlotStyle -> {Red, Green}, Frame -> True]; ?? You could even define a function setSpec that performs this SetOptions, and then other setspec2 that sets options differently, to your heart's content. – Jens Jul 31 '13 at 05:20

2 Answers2

7

On Leonid's valued opinion that the Close was inappropriate I have reopened this question.

By my interpretation this does what is requested:

SetAttributes[setSpec, HoldAllComplete]

setSpec[s_Symbol, spec__] := s /: h_[pre__, s, post___] := h[pre, spec, post]

The usage is:

setSpec[ops1,
 Filling -> {1 -> {2}},
 PlotStyle -> {Red, Green},
 Frame -> True
]

Now:

Plot[{Sin[x] + x/2, Sin[x] + x}, {x, 0, 10}, ops1]

enter image description here

Because Plot handles both Plot[. . ., option1, option2, . . .] and Plot[. . ., {option1, option2, . . .}] you can use either form in setSpec.

setSpec can also be configured to apply to only certain heads, e.g.:

SetAttributes[setSpecFor, HoldAllComplete]

setSpecFor[head_Symbol, s_Symbol, spec__] := s /: head[pre__, s, post___] := head[pre, spec, post]

And usage would be: setSpecFor[Plot, ops1, (* options *)]

This allows you to use the same name (Symbol) for separate options for different plot types.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
7

Here is another way using Evaluate:

ops1 = {Filling -> {1 -> {2}}, PlotStyle -> {Red, Green}, Frame -> True};

Plot[{Sin[x] + x/2, Sin[x] + x}, {x, 0, 10}
      , Evaluate@ops1
      , PlotLabel -> Style["Using Evaluate", 20]
]

enter image description here

Murta
  • 26,275
  • 6
  • 76
  • 166