[Matplotlib-devel] Do we already parse units for sizes (i.e. padding)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[Matplotlib-devel] Do we already parse units for sizes (i.e. padding)

Jody Klymak
Hi all,

I’m trying to work out how to do the padding on my constrained_layout
geometry manager (which is testable by the way if anyone wants to try to
break it for me: https://github.com/matplotlib/matplotlib/pull/9082).
Since I do the constraints in figure-normalized co-ordinates, my pad
variable is figure-normalized, which maybe makes sense for some plots,
but I can easily imagine it will set some people’s OCD off if the
padding is thicker in the horizotnal than the vertical because the
figure is wider than it is tall.

So I could do inches/cm, or pixels, or points. But I guess it’d be
nice to do all four. Do we already have a units parser? I couldn’t
find one. I think it’d be pretty simple: just strip the last two
characters off for unit type and pass the rest as a float.

1.0px (=1.0 px; i.e. strip spaces)
1.0cm
1.0mm
1.0in
1.0pt

I don’t think em and en would make sense in this context because we
wouldn’t know the font size, though maybe there is a sensible figure
default we could use?

Then calls like pad=0.01 and pad=‘5mm’ would both be acceptable.

a) does this exist already?
b) if not, should it?

Thanks, Jody
_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Do we already parse units for sizes (i.e. padding)

Benjamin Root
a) no, it does not exist already
b) at first blush, yes, it would be awesome, and maybe pint might be able to help us with that.

however... I would caution against getting side-tracked to add such a feature at the moment. There is a lot of hidden complexities that I think has not yet been fully appreciated yet. For example, inches and points are very different from pixels, and would require diving into the transforms system. We would also open ourselves to a fair amount of confusion from users. One time, when I was teaching an intro to matplotlib, the tutorial got derailed by the very first example by a person who was confused that a figure that was specified to be 7in x 5in wasn't that size on his laptop screen!

Ben


On Fri, Aug 25, 2017 at 1:20 PM, Jody Klymak <[hidden email]> wrote:
Hi all,

I’m trying to work out how to do the padding on my constrained_layout geometry manager (which is testable by the way if anyone wants to try to break it for me: https://github.com/matplotlib/matplotlib/pull/9082). Since I do the constraints in figure-normalized co-ordinates, my pad variable is figure-normalized, which maybe makes sense for some plots, but I can easily imagine it will set some people’s OCD off if the padding is thicker in the horizotnal than the vertical because the figure is wider than it is tall.

So I could do inches/cm, or pixels, or points. But I guess it’d be nice to do all four. Do we already have a units parser? I couldn’t find one. I think it’d be pretty simple: just strip the last two characters off for unit type and pass the rest as a float.

1.0px (=1.0 px; i.e. strip spaces)
1.0cm
1.0mm
1.0in
1.0pt

I don’t think em and en would make sense in this context because we wouldn’t know the font size, though maybe there is a sensible figure default we could use?

Then calls like pad=0.01 and pad=‘5mm’ would both be acceptable.

a) does this exist already?
b) if not, should it?

Thanks, Jody
_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel


_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Do we already parse units for sizes (i.e. padding)

Jody Klymak

Hi Ben,

On 25 Aug 2017, at 10:53, Benjamin Root wrote:

a) no, it does not exist already
b) at first blush, yes, it would be awesome, and maybe pint might be able
to help us with that.

I thought you were going to send me a beer…

however... I would caution against getting side-tracked to add such a
feature at the moment. There is a lot of hidden complexities that I think
has not yet been fully appreciated yet. For example, inches and points are
very different from pixels, and would require diving into the transforms
system.

First, I readily admit there is vast swaths of transforms and plotting things in backends I don’t appreciate!

Right now the constrained_layout manager needs to know about pixels versus figure co-ordinates, which I do now as:

invTransFig = fig.transFigure.inverted().transform_bbox
bbox = invTransFig(ax.get_tightbbox(renderer=fig.renderer))

so I’m already dealing with two of the three types of co-ordinates. I was assuming I could get to inches from pixels = inches * fig.renderer.dpi, and I am certain I can figure out centimeters. However, I’ll look at the transforms, maybe there is already one that deals with the renderer dpi.

Perhaps a relevant question for me to move forward is: what (default) units should a pad between figure elements be? tight_layout uses fraction of a font size (I assume fraction of M, though I haven’t checked). Other packages do different things. Even if we don’t want a flexible way of specifying lengths, having a consistent default would be good.

We would also open ourselves to a fair amount of confusion from
users. One time, when I was teaching an intro to matplotlib, the tutorial
got derailed by the very first example by a person who was confused that a
figure that was specified to be 7in x 5in wasn't that size on his laptop
screen!

If the figure size isn’t right, I’d assume that 12pt fonts don’t come out right either, yet I still think it makes sense to specify fonts in points (well I don’t actually - I’d much prefer mm or inches - but I doubt that’ll get much traction). So I think its sensible to specify padding and other lengths in physical units.

Anyway, I’d propose that I write a little package to do what I think is right, and then use it with constrained_layout, but with a sensible floating-point default argument in a sensible unit for the padding. If others think its a good idea then great, maybe it’d get adopted elsewhere. If not, I could remove it from constrained_layout for consistency and just use the sensible default.

Thanks, Jody

Ben


On Fri, Aug 25, 2017 at 1:20 PM, Jody Klymak <[hidden email]> wrote:

Hi all,

I’m trying to work out how to do the padding on my constrained_layout
geometry manager (which is testable by the way if anyone wants to try to
break it for me: https://github.com/matplotlib/matplotlib/pull/9082).
Since I do the constraints in figure-normalized co-ordinates, my pad
variable is figure-normalized, which maybe makes sense for some plots, but
I can easily imagine it will set some people’s OCD off if the padding is
thicker in the horizotnal than the vertical because the figure is wider
than it is tall.

So I could do inches/cm, or pixels, or points. But I guess it’d be nice to
do all four. Do we already have a units parser? I couldn’t find one. I
think it’d be pretty simple: just strip the last two characters off for
unit type and pass the rest as a float.

1.0px (=1.0 px; i.e. strip spaces)
1.0cm
1.0mm
1.0in
1.0pt

I don’t think em and en would make sense in this context because we
wouldn’t know the font size, though maybe there is a sensible figure
default we could use?

Then calls like pad=0.01 and pad=‘5mm’ would both be acceptable.

a) does this exist already?
b) if not, should it?

Thanks, Jody
_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel


_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel
Reply | Threaded
Open this post in threaded view
|

Re: Do we already parse units for sizes (i.e. padding)

Chris Barker - NOAA Federal
one thought:

Do not allow pixels to specify anything :-)

the final length-units (in, mm, points) to pixels conversion should only happen at the last minute when you need to actually render to an image.

The user can change the ppi setting at any pint until then -- their layout shouldn't change if they do.

Ideally, changing the dpi will result in exactly the same image -- other than resolution.

-CHB




On Fri, Aug 25, 2017 at 1:16 PM, Jody Klymak <[hidden email]> wrote:

Hi Ben,

On 25 Aug 2017, at 10:53, Benjamin Root wrote:

a) no, it does not exist already
b) at first blush, yes, it would be awesome, and maybe pint might be able
to help us with that.

I thought you were going to send me a beer…

however... I would caution against getting side-tracked to add such a
feature at the moment. There is a lot of hidden complexities that I think
has not yet been fully appreciated yet. For example, inches and points are
very different from pixels, and would require diving into the transforms
system.

First, I readily admit there is vast swaths of transforms and plotting things in backends I don’t appreciate!

Right now the constrained_layout manager needs to know about pixels versus figure co-ordinates, which I do now as:

invTransFig = fig.transFigure.inverted().transform_bbox
bbox = invTransFig(ax.get_tightbbox(renderer=fig.renderer))

so I’m already dealing with two of the three types of co-ordinates. I was assuming I could get to inches from pixels = inches * fig.renderer.dpi, and I am certain I can figure out centimeters. However, I’ll look at the transforms, maybe there is already one that deals with the renderer dpi.

Perhaps a relevant question for me to move forward is: what (default) units should a pad between figure elements be? tight_layout uses fraction of a font size (I assume fraction of M, though I haven’t checked). Other packages do different things. Even if we don’t want a flexible way of specifying lengths, having a consistent default would be good.

We would also open ourselves to a fair amount of confusion from
users. One time, when I was teaching an intro to matplotlib, the tutorial
got derailed by the very first example by a person who was confused that a
figure that was specified to be 7in x 5in wasn't that size on his laptop
screen!

If the figure size isn’t right, I’d assume that 12pt fonts don’t come out right either, yet I still think it makes sense to specify fonts in points (well I don’t actually - I’d much prefer mm or inches - but I doubt that’ll get much traction). So I think its sensible to specify padding and other lengths in physical units.

Anyway, I’d propose that I write a little package to do what I think is right, and then use it with constrained_layout, but with a sensible floating-point default argument in a sensible unit for the padding. If others think its a good idea then great, maybe it’d get adopted elsewhere. If not, I could remove it from constrained_layout for consistency and just use the sensible default.

Thanks, Jody

Ben


On Fri, Aug 25, 2017 at 1:20 PM, Jody Klymak <[hidden email]> wrote:

Hi all,

I’m trying to work out how to do the padding on my constrained_layout
geometry manager (which is testable by the way if anyone wants to try to
break it for me: https://github.com/matplotlib/matplotlib/pull/9082).
Since I do the constraints in figure-normalized co-ordinates, my pad
variable is figure-normalized, which maybe makes sense for some plots, but
I can easily imagine it will set some people’s OCD off if the padding is
thicker in the horizotnal than the vertical because the figure is wider
than it is tall.

So I could do inches/cm, or pixels, or points. But I guess it’d be nice to
do all four. Do we already have a units parser? I couldn’t find one. I
think it’d be pretty simple: just strip the last two characters off for
unit type and pass the rest as a float.

1.0px (=1.0 px; i.e. strip spaces)
1.0cm
1.0mm
1.0in
1.0pt

I don’t think em and en would make sense in this context because we
wouldn’t know the font size, though maybe there is a sensible figure
default we could use?

Then calls like pad=0.01 and pad=‘5mm’ would both be acceptable.

a) does this exist already?
b) if not, should it?

Thanks, Jody
_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel


_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel




--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

[hidden email]

_______________________________________________
Matplotlib-devel mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-devel