Mathtext improvements (merging into trunk)

I'm guessing that this discussion is already closed, but I would still
like to propose another option, just like the original: specify the
format in the string itself by requiring a leading '$'.

For example:

   text(x, y, r'\\sin\(x\)')

or for those functions not starting with math:

   text(x, y, r'$$phase \[0,2\\pi\)')

This is a variant on Math(r'\\sin\(x\)') which is a bit more compact.

As has been pointed out elsewhere, whether or not the string contains
tex markup is a property of the string, not a property of the function
that use the string. Note that the format keyword will be required for
all functions which have string inputs, and may cause problems if there
are multiple string inputs to the function. legend() in particular may
be a problem.

  - Paul

···

On Thu, Aug 02, 2007 at 10:31:04AM -0400, Michael Droettboom wrote:

I don't know if we ever reached consensus on how to specify math text
vs. regular text. I agree with Eric that it's down to two options:
using a new kw argument (probably format="math" to be most future-proof)
or Math('string'). I don't think I have enough "historical perspective"
to really make the call but I do have a concern about the second option
that it may be confusing depending on how "Math" is imported. (It may
have to be pylab.Math in some instances but not in others.) But I don't
have a strong objection.

Any last objections to going with the new keyword argument?

Sorry for taking so long to respond -- I was at SciPy and wanted to make sure I had the time to sit down and look at this before responding.

Paul Kienzle wrote:

I don't know if we ever reached consensus on how to specify math text vs. regular text. I agree with Eric that it's down to two options: using a new kw argument (probably format="math" to be most future-proof) or Math('string'). I don't think I have enough "historical perspective" to really make the call but I do have a concern about the second option that it may be confusing depending on how "Math" is imported. (It may have to be pylab.Math in some instances but not in others.) But I don't have a strong objection.

Any last objections to going with the new keyword argument?

I'm guessing that this discussion is already closed, but I would still
like to propose another option, just like the original: specify the
format in the string itself by requiring a leading '$'.

For example:

   text(x, y, r'\\sin\(x\)')

or for those functions not starting with math:

   text(x, y, r'$$phase \[0,2\\pi\)')

Unfortunately, this will break if text.usetex is True. Double-dollar signs in LaTeX delimits "display math" mode.

This is a variant on Math(r'\\sin\(x\)') which is a bit more compact.

>

As has been pointed out elsewhere, whether or not the string contains
tex markup is a property of the string, not a property of the function
that use the string.

I agree with you in a semantic sense. However, does that distinction really matter at the end of the day? Couldn't the same argument be made for the color or font of the text? All of them have to do with how the string is rendered. I think the oddball (for matplotlib) nature of this syntax and the import namespace details make this at least equally as cumbersome as the "markup" keyword. But it's subjective, and I'm willing to change the code if there's consensus on this.

Note that the format keyword will be required for all functions which have string inputs, and may cause problems if there are multiple string inputs to the function. legend() in particular may be a problem.

legend() doesn't currently accept a "markup" keyword, but obviously it should (if we decide to stick with the "markup" keyword). (And there are undoubtedly more holes like this to plug up). However, I don't know if it is necessary to specify the markup of each individual legend string, now that math can be easily interleaved with non-math. Isn't that just adding options where none is needed?

As I see it, the only reason to have this stuff optional at all is because it's surprising for '$'s to be delimiters. Performance is a very minor issue. I "benchmarked" global mathtext vs. optional mathtext on the "backend_driver.py" script (which admittedly is not a great benchmark, but it's something), and the timing differences seem to be below the noise threshold:

    all math: 0.78s 0.67s 0.72s
    optional math: 0.72s 0.75s 0.68s

So I don't see why in a legend you would want some labels to be interpreted as having math and some without. If you need a real dollar sign, with math on, you can always use "\$".

On a related note, there was a recent thread on matplotlib-users about usetex being a global setting:

http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg04101.html

I'm concerned about consistency and/or redundancy between this and the new markup kwarg. I don't know whether or not "usetex" being "all-or-nothing" is desirable. But we could meet in the middle by doing one of the following:

   a) only send text to LaTeX for rendering when text.usetex=True and markup="tex". (Which makes usetex=True behave a little more like usetex=False).

   b) add another value to markup, to render text with LaTeX. (If we do, I would suggest changing the kwarg to "text_renderer" and having the values be "normal", "mathtext" and "latex" or something)

   c) make markup="tex" be all-or-nothing as well (that is, keep the rcParam, but drop the kwarg.) With this flag, you're basically saying "I know how to deal with $'s".

b) is probably the most flexible (maybe too flexible, as I can't see why one would want to use all three types of rendering in the same plot). a) and b) would break backward compatibility with 0.90.1, while c) would not.

Any thoughts?

Cheers,
Mike

···

On Thu, Aug 02, 2007 at 10:31:04AM -0400, Michael Droettboom wrote:

On a related note, there was a recent thread on matplotlib-users about
usetex being a global setting:

http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg04101
.html

I'm concerned about consistency and/or redundancy between this and the
new markup kwarg. I don't know whether or not "usetex" being
"all-or-nothing" is desirable. But we could meet in the middle by doing
one of the following:

   a) only send text to LaTeX for rendering when text.usetex=True and
markup="tex". (Which makes usetex=True behave a little more like
usetex=False).

This seems like a bad idea. If I want to use tex as my text layout engine, now
I have two settings to keep track of. We'll get lots of posts asking why
latex is not being used when usetex is True.

   b) add another value to markup, to render text with LaTeX. (If we
do, I would suggest changing the kwarg to "text_renderer" and having the
values be "normal", "mathtext" and "latex" or something)

This seems reasonable. Although, if we make it so latex can be used to layout
some text but not others, I worry that we will get no end of posts
complaining about how the latex fonts dont match the mathtext or normal
fonts.

   c) make markup="tex" be all-or-nothing as well (that is, keep the
rcParam, but drop the kwarg.) With this flag, you're basically saying
"I know how to deal with $'s".

b) is probably the most flexible (maybe too flexible, as I can't see why
one would want to use all three types of rendering in the same plot).
a) and b) would break backward compatibility with 0.90.1, while c) would
not.

Any thoughts?

I think b) fits best. Maybe backward compatibility can be maintained. usetex
would be deprecated, and would set the text_renderer rcParam to latex when
True. Or does 0.90.1 already have the markup kwarg? Again, there must be a
way. The new validation mechanism in rcParams (not traits, the stuff I did
right before traits) could probably provide a route for transition without
actually breaking anything. I am pretty busy this week at work, and will be
on vacation for 11 days starting August 24, just letting you know.

Darren

···

On Monday 20 August 2007 10:18:27 am Michael Droettboom wrote:

Darren Dale wrote:

On a related note, there was a recent thread on matplotlib-users about
usetex being a global setting:

http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg04101
.html

I'm concerned about consistency and/or redundancy between this and the
new markup kwarg. I don't know whether or not "usetex" being
"all-or-nothing" is desirable. But we could meet in the middle by doing
one of the following:

   a) only send text to LaTeX for rendering when text.usetex=True and
markup="tex". (Which makes usetex=True behave a little more like
usetex=False).

This seems like a bad idea. If I want to use tex as my text layout engine, now I have two settings to keep track of. We'll get lots of posts asking why latex is not being used when usetex is True.

I agree with this point. My counter-worry is that people may be surprised when their dollar signs behave differently when usetex is on or off. Maybe people don't change that setting all that often in practice, though... We could (and I'm not necessarily advocate this), pre-process the string sent to LaTeX when usetex is True and markup == 'plain', so that the dollar signs are escaped (and will appear as dollar signs in the output).

   b) add another value to markup, to render text with LaTeX. (If we
do, I would suggest changing the kwarg to "text_renderer" and having the
values be "normal", "mathtext" and "latex" or something)

This seems reasonable. Although, if we make it so latex can be used to layout some text but not others, I worry that we will get no end of posts complaining about how the latex fonts dont match the mathtext or normal fonts.

Agreed.

   c) make markup="tex" be all-or-nothing as well (that is, keep the
rcParam, but drop the kwarg.) With this flag, you're basically saying
"I know how to deal with $'s".

b) is probably the most flexible (maybe too flexible, as I can't see why
one would want to use all three types of rendering in the same plot).
a) and b) would break backward compatibility with 0.90.1, while c) would
not.

Any thoughts?

I think b) fits best. Maybe backward compatibility can be maintained. usetex would be deprecated, and would set the text_renderer rcParam to latex when True.

That seems like a good approach, if we go with option b).

Or does 0.90.1 already have the markup kwarg?

The markup kwarg is only a couple weeks old.

Again, there must be a way. The new validation mechanism in rcParams (not traits, the stuff I did right before traits) could probably provide a route for transition without actually breaking anything.

Good point.

I am pretty busy this week at work, and will be on vacation for 11 days starting August 24, just letting you know.

Thanks. I don't think there's a huge rush to decide this (the implementation should be straightforward no matter what we decide). But it would make sense to sort this out before the next release.

Cheers,
Mike

···

On Monday 20 August 2007 10:18:27 am Michael Droettboom wrote:

Sorry to jump in late on this discussion again -- I was just trying to
use the new mathtext and ran into this use case

ax.plot(something, label=r'\\alpha=1')
ax.legend()

Paul mentioned earlier in his objection to the markup kwarg that
legend would be a problem, and there will probably be other cases too.
  I suggested once before that we adopt something like the following
rule:

  if a string has one dollar sign, treat it as plain text. If it has
more that one unquoted dollar sign, treat it as TeX, and use mathtext
or usetex depending on rc.

I know Eric objected that this kind of complexity can make things
unpleasant and lead to some difficult to debug oddities, but I think
this is a case where convenience trumps complexity. I would like the
rescind my earlier vote (now that I am trying to actually use this
stuff for real work) and support mathtext w/o kwark markup.

To support the use case above with svn, will I need to get the text
instances back from the legend and set the markup property on them?

JDH

···

On 8/21/07, Michael Droettboom <mdroe@...31...> wrote:

Darren Dale wrote:
>> I'm concerned about consistency and/or redundancy between this and the
>> new markup kwarg. I don't know whether or not "usetex" being
>> "all-or-nothing" is desirable. But we could meet in the middle by doing
>> one of the following:
>>
>> a) only send text to LaTeX for rendering when text.usetex=True and
>> markup="tex". (Which makes usetex=True behave a little more like
>> usetex=False).
>
> This seems like a bad idea. If I want to use tex as my text layout engine, now
> I have two settings to keep track of. We'll get lots of posts asking why
> latex is not being used when usetex is True.

I agree with this point. My counter-worry is that people may be
surprised when their dollar signs behave differently when usetex is on
or off. Maybe people don't change that setting all that often in
practice, though... We could (and I'm not necessarily advocate this),
pre-process the string sent to LaTeX when usetex is True and markup ==
'plain', so that the dollar signs are escaped (and will appear as dollar
signs in the output).

>> b) add another value to markup, to render text with LaTeX. (If we
>> do, I would suggest changing the kwarg to "text_renderer" and having the
>> values be "normal", "mathtext" and "latex" or something)
>
> This seems reasonable. Although, if we make it so latex can be used to layout
> some text but not others, I worry that we will get no end of posts
> complaining about how the latex fonts dont match the mathtext or normal
> fonts.

Agreed.

>> c) make markup="tex" be all-or-nothing as well (that is, keep the
>> rcParam, but drop the kwarg.) With this flag, you're basically saying
>> "I know how to deal with $'s".
>>
>> b) is probably the most flexible (maybe too flexible, as I can't see why
>> one would want to use all three types of rendering in the same plot).
>> a) and b) would break backward compatibility with 0.90.1, while c) would
>> not.
>>
>> Any thoughts?
>
> I think b) fits best. Maybe backward compatibility can be maintained. usetex
> would be deprecated, and would set the text_renderer rcParam to latex when
> True.

That seems like a good approach, if we go with option b).

> Or does 0.90.1 already have the markup kwarg?

The markup kwarg is only a couple weeks old.

> Again, there must be a
> way. The new validation mechanism in rcParams (not traits, the stuff I did
> right before traits) could probably provide a route for transition without
> actually breaking anything.

Good point.

> I am pretty busy this week at work, and will be
> on vacation for 11 days starting August 24, just letting you know.

Thanks. I don't think there's a huge rush to decide this (the
implementation should be straightforward no matter what we decide). But
it would make sense to sort this out before the next release.