You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import numpy as np
import matplotlib.pyplot as plt
plt.figure()
x = np.linspace(0.0, 1.0, 101)
y = x ** 2
plt.plot(x, y)
plt.title('sympy.lambdify\nwith UMFPACK')
plt.savefig('test.pgf')
According to the manual (and my tests), the default behavior for pgf is to center text (if left is left out). But the x value needs to be adjusted to be at the center of the plot.
Yeah, which happens if the title is one line. But if its two lines the normal text handling seems to get circumvented and the draw_text call only gets a bare string and a position.
Anyone know the call stack here? Single line titles remain text objects which svg can do a nice job of handling. but if there is a carriage return in the third title the text object isn’t passed to the draw anymore, just the two strings and their positions.
Right now the text rendering stack doesn't maintain centring for multiple-line text objects. Those objects lose their layout information and default to a more primitive rendering where the text is place based on the default renderer.
I don't see any reason two text objects could be formed at this stage, but its pretty complicated at this stage...
If you set the font to be the same as what LaTeX uses, it gets centered correctly
frommatplotlibimportrcParamsrcParams["font.serif"] ="Computer Modern Roman"rcParams["font.sans-serif"] ="Computer Modern Sans serif"rcParams["font.monospace"] ="Computer Modern Typewriter"
Seriously, anything else would be kind of hacky. (i.e #9775). If we don't know the size of fonts at some point in the layout process then not much is possible. If the user changes the fonts after matplotlib has done its job, then its kind of out of our hands.
PGF is a funny beast compared to the other backends in that it supports centered text, etc, but I don't think thats a generally available trait in other backends.
I'd say it's actually a funny beast because it lets you change the fonts. That actually seemed odd to me from when I started using it, although it is the behavior I want (I want my figures to look as seamless in my LaTeX document as possible). But it was never clear to me until this issue that you actually do want to specify the font to be the same as your LaTeX document manually in your matplotlib rc.
I actually found that rcParams thing by accident. For whatever reason, my LaTeX build was failing because it couldn't find Bitstream Vera, which I didn't want to be using anyway (I think I screwed up my TeX installation or something).
It seems to me the bug here is that it computed the font locations with Bitstream Vera Sans Serif, but the title itself got rendered with Computer Modern Sans Serif. Compare the a in lambdify with https://en.wikipedia.org/wiki/Computer_Modern#/media/File:CMU_Fonts.png vs. https://en.wikipedia.org/wiki/Bitstream_Vera#/media/File:BitstreamVera.svg for the sans serif varieties in my images in the OP. Clearly the pgf plot is using Computer Modern Sans Serif for the title, whereas png is using Bitstream Vera Sans Serif. But (I'm assuming), the locations were computed with Bitstream Vera Sans Serif. Changing the sans serif font explicitly to Computer Modern Sans fixes this, but it should probably actually use Bitstream Vera Sans for the title if that's what it's computing it with.
That assessment is based on the behavior I saw, not any reading of the code, so I could be wrong about it.
One line works because it is handled differently than two (or more) lines:
For a single-line, draw_text passes a Text object to the renderer, and that object retains all the layout information. PGF is clever and uses this.
For two lines however, the single text object doesn't work on most renderers, so it passes two separate lines to the renderer, and strips away the helpful Text object. The position it passes the renderer should be correct, but its based on the font it was supplied with, and it loses any alignment information.
The very correct solution would be for PGF to somehow get the original Text object and do its magic. But the logic required would need to be a special case for the PGF renderer, and would be hard to justify. Maybe someone clever will do it.
Is there any reason you can't use a multiline label with newlines replaced with \\? Some TeX StackExchange answers seem to suggest that works if align is set, though I admit I haven't tested it.
I see. I'm not quite clear what the difference is. I vaguely remember seeing an answer that said you could put the text in some kind of box environment. But I can't seem to find it now.
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
Activity
jklymak commentedon Nov 11, 2017
It looks like pgf left-justifies the text, which means it's position will likely be incorrect for centered display given the different fonts.
asmeurer commentedon Nov 11, 2017
According to the manual (and my tests), the default behavior for pgf is to center text (if
leftis left out). But thexvalue needs to be adjusted to be at the center of the plot.jklymak commentedon Nov 11, 2017
Yeah, which happens if the title is one line. But if its two lines the normal text handling seems to get circumvented and the
draw_textcall only gets a bare string and a position.[-]pgf title with is not centered properly[/-][+]pgf title is not centered properly[/+]jklymak commentedon Nov 12, 2017
Anyone know the call stack here? Single line titles remain text objects which svg can do a nice job of handling. but if there is a carriage return in the third title the text object isn’t passed to the draw anymore, just the two strings and their positions.
jklymak commentedon Nov 12, 2017
Right now the text rendering stack doesn't maintain centring for multiple-line text objects. Those objects lose their layout information and default to a more primitive rendering where the text is place based on the default renderer.
I don't see any reason two text objects could be formed at this stage, but its pretty complicated at this stage...
asmeurer commentedon Nov 15, 2017
If you set the font to be the same as what LaTeX uses, it gets centered correctly
jklymak commentedon Nov 15, 2017
Oh, good. I tried playing around w/ that, but didn't use Computer Modern (duh). Thats the proper solution.
asmeurer commentedon Nov 16, 2017
Why was this closed?
anntzer commentedon Nov 16, 2017
I thought the issue was solved (per @jklymak's comment "proper"solution). I can reopen it if you think it's not good enough...
jklymak commentedon Nov 16, 2017
Because you fixed it ;-)
Seriously, anything else would be kind of hacky. (i.e #9775). If we don't know the size of fonts at some point in the layout process then not much is possible. If the user changes the fonts after matplotlib has done its job, then its kind of out of our hands.
PGF is a funny beast compared to the other backends in that it supports centered text, etc, but I don't think thats a generally available trait in other backends.
asmeurer commentedon Nov 17, 2017
I'd say it's actually a funny beast because it lets you change the fonts. That actually seemed odd to me from when I started using it, although it is the behavior I want (I want my figures to look as seamless in my LaTeX document as possible). But it was never clear to me until this issue that you actually do want to specify the font to be the same as your LaTeX document manually in your matplotlib rc.
I actually found that rcParams thing by accident. For whatever reason, my LaTeX build was failing because it couldn't find Bitstream Vera, which I didn't want to be using anyway (I think I screwed up my TeX installation or something).
It seems to me the bug here is that it computed the font locations with Bitstream Vera Sans Serif, but the title itself got rendered with Computer Modern Sans Serif. Compare the
ainlambdifywith https://en.wikipedia.org/wiki/Computer_Modern#/media/File:CMU_Fonts.png vs. https://en.wikipedia.org/wiki/Bitstream_Vera#/media/File:BitstreamVera.svg for the sans serif varieties in my images in the OP. Clearly the pgf plot is using Computer Modern Sans Serif for the title, whereas png is using Bitstream Vera Sans Serif. But (I'm assuming), the locations were computed with Bitstream Vera Sans Serif. Changing the sans serif font explicitly to Computer Modern Sans fixes this, but it should probably actually use Bitstream Vera Sans for the title if that's what it's computing it with.That assessment is based on the behavior I saw, not any reading of the code, so I could be wrong about it.
jklymak commentedon Nov 17, 2017
Yes, thats exactly what happened.
One line works because it is handled differently than two (or more) lines:
For a single-line,
draw_textpasses aTextobject to the renderer, and that object retains all the layout information. PGF is clever and uses this.For two lines however, the single text object doesn't work on most renderers, so it passes two separate lines to the renderer, and strips away the helpful
Textobject. The position it passes the renderer should be correct, but its based on the font it was supplied with, and it loses any alignment information.The very correct solution would be for PGF to somehow get the original Text object and do its magic. But the logic required would need to be a special case for the PGF renderer, and would be hard to justify. Maybe someone clever will do it.
asmeurer commentedon Nov 17, 2017
Is there any reason you can't use a multiline label with newlines replaced with
\\? Some TeX StackExchange answers seem to suggest that works ifalignis set, though I admit I haven't tested it.jklymak commentedon Nov 17, 2017
Didn't work for me. tikZ lets you do that. PGF doesn't.
asmeurer commentedon Nov 17, 2017
I see. I'm not quite clear what the difference is. I vaguely remember seeing an answer that said you could put the text in some kind of box environment. But I can't seem to find it now.
jklymak commentedon Nov 17, 2017
You can do that, but you need to know how wide the box should be for it to be placed properly.
You can also specify the text as a table, and if you did it all on one line, that'd also work for you, I think.
github-actions commentedon Apr 24, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
QuLogic commentedon Apr 26, 2023
Do we just need to put some examples in the documentation for this?
github-actions commentedon Jun 10, 2024
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!