Closed senwu closed 6 years ago
Fixed by #32.
Hmm, on second look it looks like this dragon is not so easily slain. We now satisfy pip (i.e. pip install snorkel-metal
works correctly), but if somebody sets %matplotlib inline
in a jupyter notebook before they've imported metal, then we currently get a nasty warning that the matplotlib.use("TkAgg")
command I added to the repo does nothing. Nothing breaks, but it ain't pretty. I'll look for another solution.
The bug fix seems to cause another problem at least on my linux syste. Perhaps the platform should be detected (as Mac) and the backend selection made there. -c Full traceback below. This is running in the notebook with the typical %matplotlib inline at the top, as soon
import matplotlib.pyplot as plt import numpy as np
:RESULTS:
: The autoreload extension is already loaded. To reload it, use:
: %reload_ext autoreload
: /home/clee/code/eegml/metal/metal/analysis.py:13: UserWarning:
: This call to matplotlib.use() has no effect because the backend has already
: been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
: or matplotlib.backends is imported for the first time.
:
: The backend was *originally* set to 'module://ipykernel.pylab.backend_inline' by the following code:
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/runpy.py", line 193, in _run_module_as_main
: "__main__", mod_spec)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/runpy.py", line 85, in _run_code
: exec(code, run_globals)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel_launcher.py", line 16, in <module>
: app.launch_new_instance()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance
: app.start()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel/kernelapp.py", line 486, in start
: self.io_loop.start()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/tornado/platform/asyncio.py", line 132, in start
: self.asyncio_loop.run_forever()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/asyncio/base_events.py", line 422, in run_forever
: self._run_once()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/asyncio/base_events.py", line 1434, in _run_once
: handle._run()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/asyncio/events.py", line 145, in _run
: self._callback(*self._args)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/tornado/ioloop.py", line 758, in _run_callback
: ret = callback()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/tornado/stack_context.py", line 300, in null_wrapper
: return fn(*args, **kwargs)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 536, in <lambda>
: self.io_loop.add_callback(lambda : self._handle_events(self.socket, 0))
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 450, in _handle_events
: self._handle_recv()
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 480, in _handle_recv
: self._run_callback(callback, msg)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 432, in _run_callback
: callback(*args, **kwargs)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/tornado/stack_context.py", line 300, in null_wrapper
: return fn(*args, **kwargs)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 283, in dispatcher
: return self.dispatch_shell(stream, msg)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 233, in dispatch_shell
: handler(stream, idents, msg)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 399, in execute_request
: user_expressions, allow_stdin)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel/ipkernel.py", line 208, in do_execute
: res = shell.run_cell(code, store_history=store_history, silent=silent)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/ipykernel/zmqshell.py", line 537, in run_cell
: return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2662, in run_cell
: raw_cell, store_history, silent, shell_futures)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2785, in _run_cell
: interactivity=interactivity, compiler=compiler, result=result)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2901, in run_ast_nodes
: if self.run_code(code, result):
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2961, in run_code
: exec(code_obj, self.user_global_ns, self.user_ns)
: File "<ipython-input-67-08bf951f59d7>", line 2, in <module>
: get_ipython().run_line_magic('matplotlib','inline')
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2131, in run_line_magic
: result = fn(*args,**kwargs)
: File "<decorator-gen-107>", line 2, in matplotlib
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/magic.py", line 187, in <lambda>
: call = lambda f, *a, **k: f(*a, **k)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/magics/pylab.py", line 99, in matplotlib
: gui, backend = self.shell.enable_matplotlib(args.gui)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3049, in enable_matplotlib
: pt.activate_matplotlib(backend)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/IPython/core/pylabtools.py", line 311, in activate_matplotlib
: matplotlib.pyplot.switch_backend(backend)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/matplotlib/pyplot.py", line 231, in switch_backend
: matplotlib.use(newbackend, warn=False, force=True)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/matplotlib/__init__.py", line 1422, in use
: reload(sys.modules['matplotlib.backends'])
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/importlib/__init__.py", line 166, in reload
: _bootstrap._exec(spec, module)
: File "/home/clee/anaconda3/envs/metalc92py36/lib/python3.6/site-packages/matplotlib/backends/__init__.py", line 16, in <module>
: line for line in traceback.format_stack()
:
:
: matplotlib.use("TkAgg")
I also get the above warning when loading metal in a notebook.
home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/metal/analysis.py:13: UserWarning:
This call to matplotlib.use() has no effect because the backend has already
been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
The backend was *originally* set to 'module://ipykernel.pylab.backend_inline' by the following code:
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel_launcher.py", line 16, in <module>
app.launch_new_instance()
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance
app.start()
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/kernelapp.py", line 486, in start
self.io_loop.start()
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/tornado/platform/asyncio.py", line 132, in start
self.asyncio_loop.run_forever()
File "/usr/lib/python3.6/asyncio/base_events.py", line 422, in run_forever
self._run_once()
File "/usr/lib/python3.6/asyncio/base_events.py", line 1432, in _run_once
handle._run()
File "/usr/lib/python3.6/asyncio/events.py", line 145, in _run
self._callback(*self._args)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/tornado/platform/asyncio.py", line 122, in _handle_events
handler_func(fileobj, events)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/tornado/stack_context.py", line 300, in null_wrapper
return fn(*args, **kwargs)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 450, in _handle_events
self._handle_recv()
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 480, in _handle_recv
self._run_callback(callback, msg)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 432, in _run_callback
callback(*args, **kwargs)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/tornado/stack_context.py", line 300, in null_wrapper
return fn(*args, **kwargs)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 283, in dispatcher
return self.dispatch_shell(stream, msg)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 233, in dispatch_shell
handler(stream, idents, msg)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 399, in execute_request
user_expressions, allow_stdin)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/ipkernel.py", line 208, in do_execute
res = shell.run_cell(code, store_history=store_history, silent=silent)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/zmqshell.py", line 537, in run_cell
return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2666, in run_cell
self.events.trigger('post_run_cell', result)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/IPython/core/events.py", line 88, in trigger
func(*args, **kwargs)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/ipykernel/pylab/backend_inline.py", line 160, in configure_once
activate_matplotlib(backend)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/IPython/core/pylabtools.py", line 311, in activate_matplotlib
matplotlib.pyplot.switch_backend(backend)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/matplotlib/pyplot.py", line 231, in switch_backend
matplotlib.use(newbackend, warn=False, force=True)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/matplotlib/__init__.py", line 1422, in use
reload(sys.modules['matplotlib.backends'])
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/importlib/__init__.py", line 166, in reload
_bootstrap._exec(spec, module)
File "/home/lwhsiao/repos/tutorials/.venv/lib/python3.6/site-packages/matplotlib/backends/__init__.py", line 16, in <module>
line for line in traceback.format_stack()
matplotlib.use("TkAgg")
Ok, this clearly needs a different solution then, 'cause that warning, while not breaking, is long and obnoxious. We need something that lets metal use matplotlib, build successfully on pip with it in the requirements, and not output this warning when somebody imports matplotlib before importing metal. I'm traveling with limited internet, and won't be able to get to this until probably late next week at the earliest. If anyone else has a sec to take a shot at it, a PR is welcome!
Apparently matplotlib is still causing import issues. Looking at other libraries and threads, I saw this comment on scikit-optimize (https://github.com/scikit-optimize/scikit-optimize/issues/637) and I agree:
There are good reasons for why scientific libraries don't usually have matplotlib as a direct dependency: it is very platform dependent and it is usually not essential for what these libraries are trying to accomplish. Why should an optimization library depend so heavily on a visualization library?
I agree that you shouldn't try to fix dependencies for the user and I would go even further: you shouldn't even install it for them.
Take pandas as example: they have the plot() method on dataframes and series that call matplotlib.pyplot.plot() but they only import it at the time of the call and matplotlib isn't even a dependency of pandas! And the reason is very simple: pandas is a data manipulation library, the visualization part is just a kind of add-on. Leaving matplotlib out by default instead of pushing it into users that don't even need it seems like a reasonable decision to make.
I'm trying to solve a similar problem to the one described. We have a library that will depend on scikit-optimize but we are having problems because we can't depend on matplotlib platform sensitiveness and, sincerely, we just need the optimizing functions.
So I propose that we make a contrib/visualization directory. Any helpers we have that use matplotlib (all but one are in analysis.py, and that last is three-liner method we don't currently use anywhere) can be moved there and we'll add matplotlib to that directory's extra requirements.txt and remove it from the core/pip dependencies. We'll keep a notebook showing them but won't make it part of the core tests that run with travis. It's a heavy and tricky enough library and peripheral enough to metal's core functionality that it'll be nice to have proper setup for it off our plate. @ajratner agree?
@bhancock8 I like this! Also (because somewhat related): I had actually been thinking that showing the visualizations in the Basics tutorial, while nice, might give the (misleading) impression that lots of manual visualization is needed as a first step to using our approach. (Granted, it often is needed in iteration- but the idea is that it absolutely shouldn't be on first pass!). So I'm all for this, for multiple reasons!
Fixed by #62
Hi,
I got this issue when running MeTaL on Mac OS X.
There are some fixes online using either different version of python or modified python, but they are not ideal case. Is there a proper way to get rid of this issue?