Repository: mne-tools/mne-python

Issue:
mne report scaling broken
@teonlamont reported that scaling is broken. He gets reports with figures that have rotated figures like this one: https://plus.google.com/photos/albums/psjtfo8thlrdqa88m7qqn37ldkt235u54?pid=6140987061440567634&oid=108662407417175145691

@dengemann seems like git praise points to you :) https://github.com/mne-tools/mne-python/commit/011511b6846e5e76c8edf661f33e2bc35993c37c 

Also, I tried briefly and I got this: 

``` py
RuntimeError: Could not set the fontsize
```

when `scale` was less than 1.0.



Discussion:
Could you please provide a minmal report examples to reproduce this?

I cannot:

https://gist.github.com/dengemann/e24941a27bc77056461d

weird, I can't reproduce it any more too. I'll let @teonlamont post a script to reproduce the other bug while I try to figure out what I did to reproduce that.

ok, this does it:

``` py
from mne.report import Report
from mne.datasets import sample
from mne import read_evokeds
report = Report(verbose=True)

path = sample.data_path()
fname = path + '/MEG/sample/sample_audvis-ave.fif'
evoked = read_evokeds(fname, condition='Left Auditory', baseline=(None, 0),
                      verbose=True)
fig = evoked.plot(show=False)
fig.set_size_inches(3, 2)
report.add_figs_to_section(fig, captions='Left Auditory', section='evoked',
                           scale=0.2)
report.save('report.html', overwrite=True)
```

Well this is not really a bug ... you cannot scale this smaller than the smallest fontsize. It just does not throw a nice error.

see for scaling 0.5 with this example:

https://www.dropbox.com/s/oi7y927vk5jioif/Screenshot%202015-04-24%2003.24.14.png?dl=0

okay, point taken. A nicer error would be good to have.

@teonlamont could you reproduce the other problem?

If this is a release blocker it would be good to sort it out.

Teon, can you share a script to trigger the second issue? The scaling issue is not a release blocker.

> On 29 Apr 2015, at 03:58, Eric Larson notifications@github.com wrote:
> 
> If this is a release blocker it would be good to sort it out.
> 
> —
> Reply to this email directly or view it on GitHub.

``` python
p = epochs.plot_drop_log(show=False)
r.add_figs_to_section(p, 'Drop log of the events', 'Summary',
                      image_format='png', scale=.25)
```

Can you add the necessary boilerplate before those lines using the sample dataset to make it cut-and-paste runnable? It is more DRY for you to do it instead of all of the rest of us who want to test it :)

``` python
import os.path as op
import mne
from mne.report import Report 
from mne.utils import _TempDir


r = Report()
tempdir = _TempDir()
data_path = op.join(mne.datasets.sample.data_path(), 'MEG', 'sample')
raw_file = op.join(data_path, 'sample_audvis_raw.fif')
event_file = op.join(data_path, 'sample_audvis_raw-eve.fif')

raw = mne.io.read_raw_fif(raw_file)
events = mne.read_events(event_file)
epochs = mne.Epochs(raw, events, None, tmin=-.1, tmax=.4,
                    reject={'grad': 1e-10}, preload=True)
p = epochs.plot_drop_log(show=False)
r.add_figs_to_section(p, 'Drop log of the events', 'Summary',
                      image_format='svg', scale=.25)
r.save(op.join(tempdir, 'test.html'))
```

I actually see two bugs -- if the window is big, I see the one I assume you've reported:

![screen shot 2015-04-28 at 11 23 25 pm](https://cloud.githubusercontent.com/assets/2365790/7385586/a93d817a-edfd-11e4-99fb-323a727df41b.png)

But if I shrink the window, for some reason the top bar wraps and screws up the rendering further:

![screen shot 2015-04-28 at 11 23 35 pm](https://cloud.githubusercontent.com/assets/2365790/7385589/b81cff0e-edfd-11e4-9f6c-a3fc6b3f97a5.png)

these are CSS issues we've always had right?

if it's the case it's not a blocker to me.

you can click on blue arrow in progress bar to go around the second bug.

Not a blocker, at these low values of scale I'm surprised it works at all.
And normally you should not need to downscale things. Rather upscale.

2015-04-29 9:32 GMT+02:00 Alexandre Gramfort notifications@github.com:

> these are CSS issues we've always had right?
> 
> if it's the case it's not a blocker to me.
> 
> you can click on blue arrow in progress bar to go around the second bug.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/mne-tools/mne-python/issues/2014#issuecomment-97331847
> .

I agree.

This script does not run for me and I get the error that I was getting earlier. Changing the scale to a larger value, I don't see inverted fonts. @teonlamont can you reproduce this error for larger scales? If not, we just need to add a more explicit error which checks against the current font size and warns the user if it's too low.

ok. if it's easy to add a warning that would be nice, or even a note to say this only scales up images/figs.


Resolving patch:
diff --git a/mne/report.py b/mne/report.py
--- a/mne/report.py
+++ b/mne/report.py
@@ -82,7 +82,11 @@ def _scale_mpl_figure(fig, scale):
         sfactor = -((1. / scale) ** 2)
     for text in fig.findobj(mpl.text.Text):
         fs = text.get_fontsize()
-        text.set_fontsize(fs + sfactor)
+        new_size = fs + sfactor
+        if new_size <= 0:
+            raise ValueError('could not rescale matplotlib fonts, consider '
+                             'increasing "scale"')
+        text.set_fontsize(new_size)
 
     fig.canvas.draw()
 
@@ -668,6 +672,12 @@ def _build_html_slider(slices_range, slides_klass, slider_id):
 """)
 
 
+def _check_scale(scale):
+    """Helper to ensure valid scale value is passed"""
+    if np.isscalar(scale) and scale <= 0:
+        raise ValueError('scale must be positive, not %s' % scale)
+
+
 class Report(object):
     """Object for rendering HTML
 
@@ -771,6 +781,7 @@ def _add_figs_to_section(self, figs, captions, section='custom',
                           ' will throw an error.')
         figs, captions, comments = self._validate_input(figs, captions,
                                                         section, comments)
+        _check_scale(scale)
         for fig, caption, comment in zip(figs, captions, comments):
             caption = 'custom plot' if caption == '' else caption
             sectionvar = self._sectionvars[section]
@@ -800,7 +811,7 @@ def _add_figs_to_section(self, figs, captions, section='custom',
                                              caption=caption,
                                              show=True,
                                              image_format=image_format,
-                                             width=scale, comment=comment)
+                                             comment=comment)
             self.fnames.append('%s-#-%s-#-custom' % (caption, sectionvar))
             self._sectionlabels.append(sectionvar)
             self.html.append(html)
@@ -842,10 +853,10 @@ def add_figs_to_section(self, figs, captions, section='custom',
             will be appended to the end of the section
         scale : float | None | callable
             Scale the images maintaining the aspect ratio.
-            If None, no scaling is applied.
-            If float, scale will determine the relative width in percent.
-            If function, should take a figure object as input parameter.
-            Defaults to None.
+            If None, no scaling is applied. If float, scale will determine
+            the relative scaling (might not work for scale <= 1 depending on
+            font sizes). If function, should take a figure object as input
+            parameter. Defaults to None.
         image_format : {'png', 'svg'}
             The image format to be used for the report. Defaults to 'png'.
         comments : None | str | list of str
@@ -883,6 +894,7 @@ def add_images_to_section(self, fnames, captions, scale=None,
         from PIL import Image
         fnames, captions, comments = self._validate_input(fnames, captions,
                                                           section, comments)
+        _check_scale(scale)
 
         for fname, caption, comment in zip(fnames, captions, comments):
             caption = 'custom plot' if caption == '' else caption


Test patch:
diff --git a/mne/tests/test_report.py b/mne/tests/test_report.py
--- a/mne/tests/test_report.py
+++ b/mne/tests/test_report.py
@@ -134,6 +134,12 @@ def test_render_add_sections():
                                image_format='svg')
     assert_raises(ValueError, report.add_figs_to_section, figs=[fig, fig],
                   captions='H')
+    assert_raises(ValueError, report.add_figs_to_section, figs=fig,
+                  captions=['foo'], scale=0, image_format='svg')
+    assert_raises(ValueError, report.add_figs_to_section, figs=fig,
+                  captions=['foo'], scale=1e-10, image_format='svg')
+    # need to recreate because calls above change size
+    fig = plt.plot([1, 2], [1, 2])[0].figure
 
     # Check add_images_to_section
     img_fname = op.join(tempdir, 'testimage.png')