The following does not work:
However this totally works in Jupiter Notebook.
If I simply comment it out, the graph doesn't show up. (Maybe it won't show up anyways)
import pandas as pd
import matplotlib
from numpy.random import randn
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv('data/playgolf.csv', delimiter='|' )
print(df.head())
hs = df.hist(['Temperature','Humidity'], bins=5)
print(hs)
Other answers and comments have sufficiently detailed why %matplotlib inline cannot work in python scripts.
To solve the actual problem, which is to show the plot in a script, the answer is to use
plt.show()
at the end of the script.
If you are using notebook and run my_file.py file as a module
Change the line "%matplotlib inline" to "get_ipython().run_line_magic('matplotlib', 'inline')".
Then run my_file.py using this %run
It should look like this:
In my_file.py:
get_ipython().run_line_magic('matplotlib', 'inline')
In notebook:
%run my_file.py
This run my_file.py in ipython, which help avoid the bug
NameError: name 'get_ipython' is not defined
According to http://ipython.readthedocs.io/en/stable/interactive/magics.html, % is a special iPython/Jupyter command:
Define an alias for a system command.
%alias alias_name cmd defines alias_name as an alias for cmd
In standard Python, % takes the remainder when one number is divided by another (or can be used for string interpolation), so in a standard Python program, %matplotlib inline doesn't make any sense. It does, however, work in iPython, as described above.
Related
When working with my python package, a certain function has some interactive matplotlib stuff going on.
In Jupyter Notebook I always have to use the magic %matplotlib qt to switch backend in order to make it work.
However, this might seem obvious to me, but others who're trying to work with my package this is not that straight forward.
This is what I have so far in my __init__.py:
def run_from_notebook():
return hasattr(__builtins__, '__IPYTHON__')
if run_from_notebook():
# this has no effect
try:
from IPython import get_ipython
ipython = get_ipython()
except ImportError:
import IPython.ipapi
ipython = IPython.ipapi.get()
ipython.magic("matplotlib qt")
I also tried:
if matplotlib.get_backend() != 'Qt5Agg':
matplotlib.use('Qt5Agg')
but still no effect.
Is there a way to automatically switch backend in Jupyter Notebook when someone imports my package?
and also: Is there any reason it's not considered as a good practice?
It turns out that the problem is with the run_from_notebook function. When running it simply in a notebook cell it returns True, but when it's imported from my module, it returns False. The question now is rather: How to detect if code is run inside Jupyter?
For example running manually
def switch_backend_to_Qt5():
import matplotlib
if matplotlib.get_backend() != 'Qt5Agg':
matplotlib.use('Qt5Agg')
gets the job done.
EDIT :
The following function suits my needs:
import os
def run_from_notebook():
try:
__IPYTHON__
# If it's run inside Spyder we don't need to do anything
if any('SPYDER' in name for name in os.environ):
return False
# else it's probably necessary to switch backend
return True
except NameError:
return False
In PyCharm, I have one common module (called common.py) that I want to import from a few other files. It used to be working fine, until recently when I ran the program using Ctrl+Enter. Since then, I can now only run the code with Ctrl+Enter, using the normal run configuration doesn't recognize the imports; it says "unused import" and doesn't resolve references to methods in common.py. Here is the code in the file I'm trying to run:
from matplotlib import pyplot as plt
from matplotlib import colors as cl
from common import *
N = np.arange(5, 30, 1, int)
get_noiseless_eigenvalues(np.matrix([[1]]))
Both np and get_noiseless_eigenvalues aren't resolved by PyCharm, even though they are both present in common.py:
import numpy as np
def get_noiseless_eigenvalues(m: np.matrix):
return [v for v in np.linalg.eigh(m)[1] if sum(v) == 0]
I checked that the directory is indeed still marked as Sources Root. What could be the problem here?
Edit: I checked the changes with git, turns out that an empty __init__.py was added in two locations; for now, I can at least run the program normally but I'm still wondering why this happened
I'm working on a Jupyter Notebook for my master's thesis and I'd like to keep it clean. I use a lot of functions to assign categories to groups of data.
Therefore, I've decided to put all those functions in a functions.py module which I import at the start of my notebook. My notebook has the following imports:
import sys
sys.path.append('../src/') # ugly hack to be able to import the functions module
import re
import numpy as np
import pandas as pd
import seaborn as sns
import functions as fn
One of my functions uses the "re" module for matching strings with regex. When I called the said function I get NameError: ("name 're' is not defined", 'occurred at index 0') so I figured I had to import re at the beginning of my functions.py file. This didn't change anything. So I even tried to put import re in the function body, but it wouldn't work either.
I have absolutely no idea why re doesn't work despite trying to import it everywhere.
Note: my functions worked correctly when I was defining and using them from the notebook so I know for certain it's not a bug in my function.
Solved my own issue, the answer is stupidly simple: Jupyter doesn't take into account any edits to an imported module even if you reimport it. If you make any changes to a module you have to shut down the kernel and restart it, import again and the edits will work.
In my particular case I had added import re to my functions.py but Jupyter didn't take it into account until I restarted the kernel.
In a notebook, you can use the importlib library and call importlib.reload(module) instead of restarting the kernel
I'm attempting to set the numpy print options using a signal handler on the window resize event. Don't want to make the connection until numpy has been imported, and don't want to import numpy automatically at python startup. I've got it almost-working with the code below:
# example.py
import wrapt
#wrapt.when_imported('numpy')
def post_import_hook(numpy):
import signal
try:
from shutil import get_terminal_size
except ImportError:
# Python 2
from shutil_backports import get_terminal_size
def resize_handler(signum=signal.SIGWINCH, frame=None):
w, h = get_terminal_size()
numpy.set_printoptions(linewidth=w)
print('handled window resize {}'.format(w))
resize_handler()
signal.signal(signal.SIGWINCH, resize_handler)
It works in vanilla python REPL (test with python -i example.py and resize the terminal a bit). But it doesn't work in ipython when the same code is added to my startup ipython config, and I don't understand why.
I'm not fixed on this particular approach (that's just what I've tried so far), so I'll phrase the question more generally:
How can numpy correctly fill to the terminal width automatically in ipython?
You can use print(np.arange(200)), for example, to check numpy's line wrapping behaviour.
Inspired by the standard fix for printing large arrays without truncation, I tried setting the line width to infinity. This seems to be working fine both in the REPL and in ipython, so I suggest this workaround:
import numpy
numpy.set_printoptions(linewidth=numpy.inf)
This doesn't explain why your fix doesn't work for ipython, but in case the above line doesn't mess with anything unexpected, it should make printing immune to resizing.
Sometimes I run my script via ssh. This answer told me to set up
import matplotlib
#matplotlib.use('Agg') # Must be before importing matplotlib.pyplot or pylab!
import matplotlib.pyplot as plt
when I get the undefined SCREEN error by running the script via ssh. However with that preamble I cannot view the graphs interactively when I run the script on my local machine.
What's the condition to check if the screen is defined? I'd like to do
if SCREEN == None:
matplotlib.use('Agg')
How's the proper code for that, how can I check this?
It looks like an easiest way to do this is to check 'DISPLAY' environment variable
import os
# 'DISPLAY' will be something like this ':0'
# on your local machine, and None otherwise
if os.environ.get('DISPLAY') is None:
matplotlib.use('Agg')