12
$\begingroup$

I am confused about when to use a simple list of style options, the Directive function or the Style function.

As shown below, for simple situations at least, they seem entirely equivalent which suggests personal preference.

This question regarding the requirement for the use of Directive indicates that aside from a some small edge cases, Directive is mostly preferred as easier to read and has the useful property that a single compound graphics Directive can be stored as a variable and referenced where needed.

That would have been enough for me except the Elementary Introduction Chapter 8 doesn't mention either of these and introduces Style. Style seems to be more widely applicable so perhaps it was chosen to minimise the number of functions introduced to a new user.

I am mostly interested in which method a beginner should start with as their default rather than trying to use all 3 at random - I'm leaning toward Directive since it translates well to Plot but again, all methods work so what am I missing?

 {Graphics[{
       Red, Thick, Circle[],
       Blue, Rectangle[]
       }]
     ,
     Graphics[{
       Directive[Red, Thick], Circle[],
       Directive[Blue], Rectangle[]
       }]
     ,
     Graphics[{
       Style[Circle[], Red, Thick],
       Style[Rectangle[], Blue]
       }]
     }
$\endgroup$
5
  • $\begingroup$ Related: (135062) $\endgroup$
    – Mr.Wizard
    May 12 '17 at 6:33
  • $\begingroup$ "This question regarding the requirement for the use of Directive indicates that aside from a some small edge cases, it is mostly preferred as easier to read" -- You're saying what exactly is mostly preferred? Using Directive? Using a sequence of directives instead? Something else? $\endgroup$
    – jjc385
    May 12 '17 at 8:04
  • 1
    $\begingroup$ Works: Graphics[{GrayLevel[Log[2]], Disk[]}] Does not work: Graphics[{Style[Disk[], GrayLevel[Log[2]]]}] $\endgroup$
    – Szabolcs
    May 12 '17 at 9:28
  • 1
    $\begingroup$ Works: style = Directive[Red, Thick]; Graphics[{style, Circle[]}]. Does not work: style = {Red, Thick}; Graphics[{style, Circle[]}]. Directive was introduced to address this programming problem, imo. -- Note your Style version is converted to Graphics[{{RGBColor[1, 0, 0], Thickness[Large], Circle[{0, 0}]}, {RGBColor[0, 0, 1], Rectangle[{0, 0}]}}], i.e., your first form, in the output in the front end. $\endgroup$
    – Michael E2
    May 14 '17 at 2:54
  • 1
    $\begingroup$ Something you can do with Style: Graphics[Style[{Circle[], Rectangle[], Point[{0.5, 0.5}]}, "foo"]], where "foo" is a style you have defined in your stylesheet. It can automatically style most graphics primitives in a consistent way (other than Circle[] for some reason -- an oversight???). $\endgroup$
    – Michael E2
    May 14 '17 at 3:17
1
$\begingroup$

First consider these points:

  • This question borders on asking for an answer that is a matter of opinion, which is usually frowned upon by SE. However, I think there are some objective points that can be made.
  • The differences between wrapping graphics primitives with List or Directive is subtle and in my view already adequately treated. So for purposes of this answer Directive can be considered invisible.
  • I find your example a little too simple to bring out the difference between wrapping graphics primitives with List or Style that I want to discuss, so consider this example instead:
GraphicsRow @
  {Graphics[{FaceForm[], EdgeForm[{Thick, Red}], Disk[], Blue, Rectangle[]}],
   Graphics[{{FaceForm[], EdgeForm[{Thick, Red}], Disk[]}, Blue, Rectangle[]}],
   Graphics[{Style[Disk[], FaceForm[], EdgeForm[{Thick, Red}]], Style[Rectangle[], Blue]}],
   Graphics[
     {Style[Disk[], FaceForm[], EdgeForm[{Thick, Red}]], 
      Style[Rectangle[], FaceForm[], EdgeForm[{Thick, Red}]]}],
   Graphics[{Style[{Disk[], Rectangle[]}, FaceForm[], EdgeForm[{Thick, Red}]]}]}

graphics

The important thing to notice in the my example is that. unless constrained list boundaries, graphic primitives propagate forward. In the 1st graphics expression of the mt example you can see that FaceForm and EdgeForm, being unconstrained by any list boundaries, propagate to exert controls over how the rectangle is drawn, completely suppressing the Blue primitive. In the 2nd graphics expression. FaceForm and EdgeForm are enclosed in a sublist and confined to act only on the disk. Wrapping primitives with Directive is invisible as far a forward propagation is concerned.

On the other hand, wrapping with Style is like placing the graphic object that appears as 1st argument into its own sublist along with the primitives that comprise the remaining arguments — they never propagate forward. Therefore, the 3rd graphics expression looks the same as the 2nd, not the 1st. To get the effect of the 1st graphics expression. I must repeat the arguments of the 1st Style expression in the 2nd one. That's rather clumsy. The last graphics expression shows a better way to use Style in this case, but in general using sublists is much more flexible than using Style when building complicated graphics.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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