preliminary detachable axis patch

Any other comments/questions?

Hey Andrew, just did a quick read through the diff and have a few
meandering comments meant solely to confuse and perplex :slight_smile:

Rather than all this cruft in rc

  axes.spineLeftOn : True
  axes.spineRightOn : True
  axes.spineBottomOn : True
  axes.spineTopOn : True
  axes.spineLeftPad : 0
  axes.spineRightPad : 0
  axes.spineBottomPad : 0
  axes.spineTopPad : 0

How about

  xaxis.spine1 = 0
  xaxis.spine2 = 0
  yaxis.spine1 = 0
  yaxis.spine2 = 0

Or xaxis spine1 is left and spine2 is right; for yaxis bottom and top.
Use None to turn the spine off. Otherwise use a floating point value
to represent the pad.

You would need a new rc method none_or_float, which will eventually
become a trait. Some care would have to be taken with this approach
though. If the text locations and tick line locations are using
*delegation*, None could cause some trouble. But if we use observer,
then we could simply toggle the visibility to off upon setting None.
This would work pretty well.

In the midst of this refactor, it would be nice to support three tick
position (inside, outside, center) rather than use the tick1inward
boolean you suggest. As you know we already have TICKUP, TICKDOWN
TICKLEFT and TICKRIGHT line styles. It would be trivial to add
TICK_HORIZONTAL_CENTER and TICK_VERTICAL_CENTER to support these three
tick placement schemes. We then do away with inward and outward and
simply use the tick line-style to indicate it's position. The trick
for doing label placement would be to query the tick line for top,
left, bottom and right. Then the only other param we need is the pad
in points that separates the label from the tick, right?

  xaxis.tick.alignment = 'inside' # inside | outside | center
  xaxis.tick.labelpad = 5 # distance from tickline in points

Hmm, the project is growing. I think there is something to be said
for doing this axis refactor once, generally, and right, though.

You also have to be a little careful here

      self._tick1PadPixels = self.figure.dpi*Value(tick1Pad)*Value(1/72.0)

because changes to tick11pad will not be reflected in
self._tick1PadPixels. Compare with

      self.tick1Pad = Value(tick1Pad)
      self._tick1PadPixels = self.figure.dpi*self.tick1Pad*Value(1/72.0)

Then if later on you do self.tick1Pad.set(7) the tick1padPixels attr
is automagically updated

A lot of things I tried to solve with lazy values are addressed by
delegation and observers in traits though, so we may want to go for a
more traity impl.

On a related note, it would be really nice to develop a layout object
that was easy to use that was trait and mpl transform aware, so you
could rather easily say

  val = to_the_right_of(x, 5*points)
  
Lazy values take you part of the way -- we'd also need all objects to
report their extent (pretty easy, but can be expensive for some artist
styles). With get_extent implemented for all artists, you could build
something like this will lazy values, but the syntax of constructing
these things is a bit awkward, and matplotlib doesn't allow you to use
lazy values and float interchangeably, which would be nice for example
when creating text instances. So a bit of redesign to support this
kind of layout would make your job a lot easier.

Anyway, more sketchy thoughts that concrete ideas.... Thanks for the
preliminary attempt!

JDh

    > Any other comments/questions?

Hey Andrew, just did a quick read through the diff and have a few
meandering comments meant solely to confuse and perplex :slight_smile:

No, I like your suggestions...

Rather than all this cruft in rc
<snip>
How about

  xaxis.spine1 = 0
  xaxis.spine2 = 0
  yaxis.spine1 = 0
  yaxis.spine2 = 0

Or xaxis spine1 is left and spine2 is right; for yaxis bottom and top.
Use None to turn the spine off. Otherwise use a floating point value
to represent the pad.

Yes, I like your suggestion.

You would need a new rc method none_or_float, which will eventually
become a trait. Some care would have to be taken with this approach
though. If the text locations and tick line locations are using
*delegation*, None could cause some trouble. But if we use observer,
then we could simply toggle the visibility to off upon setting None.
This would work pretty well.

I think we might want a spine position variable separate from a spine visibility variable. It's conceivable, although seemingly unlikely, that people would want to move the spine but have it invisible such that the tick origins are offset...

In the midst of this refactor, it would be nice to support three tick
position (inside, outside, center) rather than use the tick1inward
boolean you suggest. As you know we already have TICKUP, TICKDOWN
TICKLEFT and TICKRIGHT line styles. It would be trivial to add
TICK_HORIZONTAL_CENTER and TICK_VERTICAL_CENTER to support these three
tick placement schemes. We then do away with inward and outward and
simply use the tick line-style to indicate it's position. The trick
for doing label placement would be to query the tick line for top,
left, bottom and right. Then the only other param we need is the pad
in points that separates the label from the tick, right?

Yes, and then another step where I think we'd need the bounding boxes for the ticklabels to get the pad for the axis label (axis title).

Hmm, the project is growing. I think there is something to be said
for doing this axis refactor once, generally, and right, though.

Agreed. I was fantasizing this morning about how, if we push the transforms into the backend, generalizing the whole thing to 3D and, for example, making an OpenGL backend wouldn't be the daunting task it once might've seemed. MPL's (2D) transforms now seem to be an example of parallel evolution to OpenGL's (3D) transforms. Furthermore, we could maybe support 3D in the frontend while allowing backends to implement at their own pace, throwing a NotImplementedError when the z transform becomes non-identity and if z values are non-zero... Maybe we could write a middle-layer (wrapper) backend which handles the 3D->2D transforms for the pure 2D backends. This would handle the projective transformation but preserve zorder. Anyhow, just a fantasy for the moment, but tantalizing.

You also have to be a little careful here

      self._tick1PadPixels = self.figure.dpi*Value(tick1Pad)*Value(1/72.0)

because changes to tick11pad will not be reflected in
self._tick1PadPixels. Compare with

      self.tick1Pad = Value(tick1Pad)
      self._tick1PadPixels = self.figure.dpi*self.tick1Pad*Value(1/72.0)

Then if later on you do self.tick1Pad.set(7) the tick1padPixels attr
is automagically updated

Yeah, I was running out of steam last night at 3 in the morning and got lazy, just wanting to get the thing to work. I knew about this...

A lot of things I tried to solve with lazy values are addressed by
delegation and observers in traits though, so we may want to go for a
more traity impl.

Agreed.

On a related note, it would be really nice to develop a layout object
that was easy to use that was trait and mpl transform aware, so you
could rather easily say

  val = to_the_right_of(x, 5*points)

Lazy values take you part of the way -- we'd also need all objects to
report their extent (pretty easy, but can be expensive for some artist
styles). With get_extent implemented for all artists, you could build
something like this will lazy values, but the syntax of constructing
these things is a bit awkward, and matplotlib doesn't allow you to use
lazy values and float interchangeably, which would be nice for example
when creating text instances. So a bit of redesign to support this
kind of layout would make your job a lot easier.

This would really cool. It's beyond my brain capacity right now to think about implementation...

Anyway, more sketchy thoughts that concrete ideas.... Thanks for the
preliminary attempt!

I think moving to traits would be a wise first step, so I'll hold off for now until we get traits implemented. What needs to happen first to implement traits? Change rcParams to be traits aware? I've been ignoring the threads about re-vamping the rcParams format and reader, so I'm clueless about what's going on in that department. Anyhow, I'm in no great hurry to get detachable axis spines working (as you know!), so I can happily return to this later.

Cheers!
Andrew

···

On Feb 13, 2005, at 1:00 PM, John Hunter wrote: