johannesjmeyer / rsmf

Right-size my figures
174 stars 9 forks source link

Can't use fill_between with revtex4-1 and custom formatter #19

Closed drtobybrown closed 3 years ago

drtobybrown commented 3 years ago

Hi, really nice package - thanks!

I'm running into issues formatting plots that use matplotlibs fill_between(). E.g.,


import rsmf
import matplotlib.pyplot as plt
import numpy as np

formatter = rsmf.setup(r"\documentclass[a4paper,12pt,noarxiv]{revtex4-1}")

fig = formatter.figure(aspect_ratio=.5)

x = np.arange(0.0, 2, 0.01)
y = np.sin(2 * np.pi * x)

plt.fill_between(x, 0, y)
plt.ylabel('between y and 0')

plt.savefig("example.pdf")

Throws the following error:

[long pdf latex error]
...

! Dimension too large.
<to be read again> 
                   \relax 
l.848 ...to{\pgfqpoint{2.533096in}{-251.296998in}}
                                                  %
!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on figure.log.

It also fails with the following custom formatter but runs fine with the quantumarticle documentclass in rsmf.setup() .

formatter = CustomFormatter(
    columnwidth=246 * 0.01389,
    wide_columnwidth=512 * 0.01389,
    fontsizes=11,
    pgf_preamble=r"\usepackage{lmodern}",
)

I'm using rsmf 0.2 and matplotlib 3.3.4

johannesjmeyer commented 3 years ago

Hi @drtobybrown, I'll have a look as soon as possible!

johannesjmeyer commented 3 years ago

So, @drtobybrown, I've been digging a bit. I was able to reproduce the error, although with a different failure point, but I think that was to be expected for different latex distributions. I now also add an explicit preamble for revtex and it fixes the error for me.

Would you be so kind and re-install from the fix_fill_between branch? The following should work:

pip install git+https://github.com/johannesjmeyer/rsmf.git@fix_fill_between --upgrade

I actually have no idea why this fixes the issue or why it arises in the first place, I suspect this is a bug in the pgf backend of matplotlib.

PS: Thanks a lot for your very clear and concise issue! That makes helping really easy.

drtobybrown commented 3 years ago

Interesting, it didn't fix the issue for me but did change the error.

The example above now throws with matplotlib 3.3.4 and rsmf 0.2@fix_fill_between:

....
ValueError: Error processing '−1'
LaTeX Output:

! Package inputenc Error: Unicode character − (U+2212)
(inputenc)                not set up for use with LaTeX.

See the inputenc package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

<*> ...size{10.000000}{12.000000}\selectfont −1}

!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on texput.log.

....

However, a bit of googling found this issue which seems to have been fixed in the matplotlib master branch.

Installing that (pip install git+https://github.com/matplotlib/matplotlib.git) fixes the issue for me using both the rsmf master and fix_fill_between branches on the example above.

drtobybrown commented 3 years ago

Carrying on here because I ran into this while trying to fix the issue above but I *think* this is a separate issue. Let me know if you'd like me to make one.

I get a "Dimension too large" error when plotting with a log scale


formatter = rsmf.setup(r"\documentclass[a4paper,12pt,noarxiv]{revtex4-1}")

fig = formatter.figure(aspect_ratio=.5)

_, ax = plt.subplots()

x = np.arange(1e-5, 2, 0.01)
y = np.sin(2 * np.pi * x)

ax.fill_between(x, 0, y)

ax.set_yscale('log') # this is the problem
plt.savefig('example.pdf')

Throws

...
! Dimension too large.
<to be read again> 
                   \relax 
l.420 ...to{\pgfqpoint{0.647977in}{-650.241700in}}
                                                  %
!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on figure.log.

There's a long discussion of the issue here. This is possibly a solution but I can't obviously see if it has been merged.

matplotlib 3.3.4@master and rsmf 0.2

johannesjmeyer commented 3 years ago

Thanks a lot @drtobybrown for finding the solution to this! I guess then the fix_fill_between branch can also be dropped.

But I think I can help you with your other problem: you fill between 0 and the graph, but 0 is a value that can not exist on a log scale (it would be at minus infinity). So if you replace 0 in your code with min(y) or use a symlog scale this should work (it works on my end).

drtobybrown commented 3 years ago

Yep, looks good to me. And thank you, sometimes one can miss the wood for the trees.