Repository: jupyter/docker-stacks

Issue:
error importing matplotlib in scipy-notebook
Hi,

I just pulled a fresh copy of jupyter/scipy-notebook from dockerhub. When I run

```
import matplotlib.pyplot as plt
```

I get the following error:

```
ImportErrorTraceback (most recent call last)
<ipython-input-5-eff513f636fd> in <module>()
----> 1 import matplotlib.pyplot as plt

/opt/conda/lib/python3.5/site-packages/matplotlib/pyplot.py in <module>()
    112 
    113 from matplotlib.backends import pylab_setup
--> 114 _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
    115 
    116 _IP_REGISTERED = None

/opt/conda/lib/python3.5/site-packages/matplotlib/backends/__init__.py in pylab_setup()
     30     # imports. 0 means only perform absolute imports.
     31     backend_mod = __import__(backend_name,
---> 32                              globals(),locals(),[backend_name],0)
     33 
     34     # Things we pull in from all backends

/opt/conda/lib/python3.5/site-packages/matplotlib/backends/backend_qt4agg.py in <module>()
     16 
     17 
---> 18 from .backend_qt5agg import FigureCanvasQTAggBase as _FigureCanvasQTAggBase
     19 
     20 from .backend_agg import FigureCanvasAgg

/opt/conda/lib/python3.5/site-packages/matplotlib/backends/backend_qt5agg.py in <module>()
     13 
     14 from .backend_agg import FigureCanvasAgg
---> 15 from .backend_qt5 import QtCore
     16 from .backend_qt5 import QtGui
     17 from .backend_qt5 import FigureManagerQT

/opt/conda/lib/python3.5/site-packages/matplotlib/backends/backend_qt5.py in <module>()
     29     figureoptions = None
     30 
---> 31 from .qt_compat import QtCore, QtGui, QtWidgets, _getSaveFileName, __version__
     32 from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
     33 

/opt/conda/lib/python3.5/site-packages/matplotlib/backends/qt_compat.py in <module>()
    135     # have been changed in the above if block
    136     if QT_API in [QT_API_PYQT, QT_API_PYQTv2]:  # PyQt4 API
--> 137         from PyQt4 import QtCore, QtGui
    138 
    139         try:

ImportError: libicui18n.so.56: cannot open shared object file: No such file or directory
```

everything is internal to the docker container, so this shouldn't be an issue with my machine. Everything except matplotlib seems to be working. Also, I know very little about Qt and how Python interacts with it. Google doesn't turn up anything either.

Any ideas??



Discussion:
Try putting %matplotlib inline in your notebook before you import the library. You shouldn't need to do this as we've fixed this bug a few times in the past by adding the libraries needed to make matplotlib importable before setting the renderer backend. But it looks like things hav regressed again. Maybe libicui18n use to be installed implicitly but now it is not. 

Ref #110 but different lib.

this fixed the issue! Thanks a lot

To avoid hitting this problem again, I think we should preconfigure the IPython kernel for matplotlib inline mode. Users can override that default with the magic if desired (e.g., `%matplotlib notebook`).


Resolving patch:
diff --git a/scipy-notebook/mplimporthook.py b/scipy-notebook/mplimporthook.py
new file mode 100644
--- /dev/null
+++ b/scipy-notebook/mplimporthook.py
@@ -0,0 +1,55 @@
+"""Startup script for IPython kernel.
+
+Installs an import hook to configure the matplotlib backend on the fly.
+
+Originally from @minrk at 
+https://github.com/minrk/profile_default/blob/master/startup/mplimporthook.py
+Repurposed for docker-stacks to address repeat bugs like
+https://github.com/jupyter/docker-stacks/issues/235.
+"""
+import sys
+from IPython import get_ipython
+
+class MatplotlibFinder(object):
+    """Import hook that notices when matplotlib.pyplot or pylab is imported
+    and tries to configure the matplotlib backend appropriately for the
+    environment.
+    """
+    _called = False
+    
+    def find_module(self, fullname, path=None):
+        if self._called:
+            # already handled
+            return
+        
+        if fullname not in ('pylab', 'matplotlib.pyplot'):
+            # not matplotlib
+            return
+        
+        # don't call me again
+        self._called = True
+        
+        try:
+            # remove myself from the import hooks
+            sys.meta_path = [loader for loader in sys.meta_path if loader is not self]
+        except ValueError:
+            pass
+        
+        ip = get_ipython()
+        if ip is None:
+            # not in an interactive environment
+            return
+            
+        if ip.pylab_gui_select:
+            # backend already selected
+            return
+            
+        if hasattr(ip, 'kernel'):
+            # default to inline in kernel environments
+            ip.enable_matplotlib('inline')
+        else:
+            print('enabling matplotlib')
+            ip.enable_matplotlib()
+
+# install the finder immediately
+sys.meta_path.insert(0, MatplotlibFinder())
\ No newline at end of file


Test patch: