Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm looking for a description of the structure of Graphics objects, aimed at the advanced Mathematica programmer.


The motivation for this question is the following. I have several Module-type functions that, as part of their operation, have to manipulate Graphics objects (primarily those generated by plotting commands). I find that these functions often produce undesired results, and the reason is, invariably, that the function has assumed something about the structure of Graphics objects that turns out not to hold in general. Hence, I want to learn more about the internal structure of the Graphics objects generated by Plot, ListPlot, and friends.

Unfortunately, I cannot distill my overall state of confusion into one or two concrete questions. I have a ton of questions, but from my ignorant vantage point, I cannot rank these questions in order of importance. Here's an example out of many I could give: "why do the lists of "primitives" in so many of the Graphics objects that I produce with plotting commands begin and end with empty lists?" For all I know, the answer to this question could just as easily be hugely illuminating, or be utterly banal, or, worse yet, may give rise to further questions.


I've read the documentation for Graphics and the tutorial The Structure of Graphics (which, despite the promising-sounding title, did not shed as much light as I'd hoped). (I've also watched the Graphics Language Quick Start, which is generally instructive, but, as its name suggests, far more high-level and beginner-oriented than what I'm looking for.)

share|improve this question
    
How much do you know about computer 3D graphics in general? Mathematica's approach makes a lot of sense if you have some background in say Direct3D or OpenGL. –  Hector Sep 20 '13 at 16:47
    
@Hector: the answer is "not much", I'm afraid. I'm interested in 2D graphics at the moment, though... –  kjo Sep 20 '13 at 16:55

1 Answer 1

up vote 11 down vote accepted

A Graphics object describes what amounts to a state-machine. Each object allowed in the primitive list has one of three actions associated with it

  1. add to state,
  2. display something while accounting for the current state, and
  3. save/restore state.

Note, this can be modeled by a stack based system quite easily. According to the documentation, the first two make up the primitives and the last one is done by encapsulating primitives in a List. Truthfully, I think the language used by the documentation is a little rough here, so I would like to make the distinction between directives which add to the state and primitives which are displayed. In light of the above model, let us examine a simple Graphics object

Graphics[{Blue, {EdgeForm[{Red, Thick}], Disk[]}, Disk[{1,0}]}]

enter image description here

which can be interpreted in terms of the following steps:

  1. { -> Save state. state == {}
  2. Blue -> AppendTo[state, Blue]. state == {Blue}
  3. { -> Save state. state == {Blue}
  4. EdgeForm[{Red, Thick}] -> AppendTo[state, EdgeForm[{Red, Thick}]]. state == {Blue, EdgeForm[{Red, Thick}]}
  5. Disk[] -> Display {Blue, EdgeForm[{Red, Thick}]], Disk[]}
  6. } -> Restore state. state == {Blue}
  7. Disk[{1,0}] -> Display {Blue, Disk[{1,0}]}

So, then

Graphics[{Blue, {Red}, Disk[]}]

should result in a blue disk because Red has been isolated by being wrapped in a List. This also explains why

Graphics[{Blue, {}, Disk[]}]

also generates a blue disk. An empty list has no effect, and just hinders readability.

This is a slight over-simplification, as state should be thought of as a set of registers, and each directive only effects a specific one. In most cases, only a single function effects a specific register, the color register, though, is effected by many, such as Hue, RGBColor, etc. For example,

Graphics[{Blue, Red, Disk[]}]

produces a red disk because Red changed the color register, but

Graphics[{Blue, EdgeForm[Red], Disk[]}]

produces a blue disk with a red edge because EdgeForm does not effect the color register.

There are four additional primitives that need to be discussed: Directive, GraphicsGroup, GraphicsComplex, and Inset. For all purposes that I'm aware of,

Directive[{directive..}] == Directive[directive ..] == Sequence[directive ..]

as far as Graphics is concerned. Its primary use is to group directives together where otherwise you can only supply one, such as in BaseStyle. The last three are container types like List in that they save and restore state upon entry and exit.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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