IPython plotting inline not showing - matplotlib

I have the following code in IPython running IPython QT Console on Linux.
%pylab inline
Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].
For more information, type 'help(pylab)'.
fig = figure()
ax = fig.add_axes()
ax = fig.add_axes([0,500, 0, 5000])
ax.plot([1,2,3,44], [4,4,55,55])
Out[5]: [<matplotlib.lines.Line2D at 0x3d8e7d0>]
fig
Out[6]: <matplotlib.figure.Figure at 0x3d25fd0>
fig.show()
/usr/lib/pymodules/python2.7/matplotlib/figure.py:362: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure
"matplotlib is currently using a non-GUI backend, "
I've been struggling to make this work for some time, I've tried changing the backend manually with matplotlib.use() to Qt4Agg, GTK etc with no luck. This also happens in IPython notebook even when I call display().
Any ideas how to get the inline plotting working?
Marked Jakob's answer as the answer, but both are true actually. I had to replace the matploblibrc file with a new copy, started IPython QT Console with --pylab=None then manually entered %pylab inline in the console. Somehow this fixed the problem.

The axis object is defined incorrectly, this prevents matplotlib from rendering.
Remove the first ax = fig.add_axes(), and replace the second line with
ax = fig.add_axes([0, 0, 1, 1]).
The add_axes method requests the size of the axis in relative coordinates, in the form left, bottom, width, height with values between 0 and 1, see e.g. matplotlib tutorial.
You may also try fig.add_subplot(111) instead of fig.add_axes() or fig,ax = subplots() to create your figure and axis objects. The latter assumes that you have populated the interactive namespace matplotlib (%pylab) call in IPython.

It looks like your matplotlib build was compiled without a gui backend.
This is done when either a) it's explicitly specified (handy for webservers), or b) the required libraries for at least one gui backend aren't present (e.g. no Tk, Gtk, Qt, etc).
How did you install matplotlib?
If you compiled it from source, make sure that you have the development libraries for at least Tk installed and that your python install was compiled with Tk support (it is by default). If you installed it from your distro's repositories, whoever built the package built it without gui support, and you'll need to install it from another source.

Related

Different behaviour of ipywidgets.interactive_output() on Windows and macOS

I wanted to learn how to use interactive plots in Jupyter Notebook and created a script that updates a figure based on the current values of two sliders. The idea is simply that when the value of one of the sliders changes the figure should be updated.
This worked fine when I first ran the code on my Windows PC (using Windows 10). However, when I then ran the same code on my MacBook (using macOS Monterey 12.6.1), the figure is not updated but a new figure is created every time I change the value of one of my sliders.
Please find a MWE below:
import numpy as np
import matplotlib.pyplot as plt
import ipywidgets as widgets
%matplotlib widget
# Create two sliders
slider1 = widgets.IntSlider(value=4, min=0, max=10, step=1,
description='Slider1', continuous_update = False)
slider2 = widgets.IntSlider(value=8, min=0, max=10, step=1,
description='Slider2', continuous_update = False)
# Some function that plots the result based on the current values of the sliders
def plotResult(a, b):
plt.close('all')
plt.figure()
plt.hlines(a+b, xmin=0, xmax=10)
# Create interactive plot
interactive_plot = widgets.interactive_output(plotResult, {"a":slider1, "b":slider2})
ui = widgets.HBox([slider1, slider2])
display(ui, interactive_plot)
When I run the above code in a cell in my Jupyter Notebook, I get the following output:
(https://i.stack.imgur.com/NX02T.png).
When I now change any of the sliders, on Windows my figure is "updated in-place", while on macOS a new figure is created everytime (every figure newly created figure is labeled as 'Figure 1'). I don't understand why this is happening as I explicitly close all currently opening figures at the beginning of plotResults(a,b) by using the command plt.close('all').
I thought that since every newly created figure on macOS is labeled 'Figure 1' the problem could be that on macOS the cells are not refreshed. Thus, I additionally imported the module IPython using import IPython and then added the command IPython.display.clear_output(wait=True) after the first line of plotResults(a,b). However, this did not work and the problem persisted.
I also tried to use a different Matplotlib backend such as %matplotlib ipympl or %matplotlib nbagg instead of %matplotlib widget but this also did not help anything.

Turning off specgram auto-plotting in Jupyter notebook

I'm using Matplotlib's specgram function, which has a form like:
Pxx, freqs, bins, im = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900)
where Pxx, freqs, bins, and im represent the periodogram, frequency vector, center of time bins, and the image.AxesImage instance. Additionally, you can feed in arguments (**kwargs) that get passed onto imshow.
I cannot seem to use specgram in a Jupyter Notebook, without producing a plot automatically. What argument can I pass into specgram that will stop it from plotting automatically?
I am not calling any plt.show() command. I've tried adding a semi-colon at the end of the line, and I've tried setting the final argument (im) as nothing, like this:
Pxx, freqs, bins, _ = specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900);
but nothing seems to work.
From the PyPlot.jl docs: https://github.com/JuliaPy/PyPlot.jl#non-interactive-plotting
If you use PyPlot from an interactive Julia prompt, such as the Julia command-line prompt or an IJulia notebook, then plots appear immediately after a plotting function (plot etc.) is evaluated.
However, if you use PyPlot from a Julia script that is run
non-interactively (e.g. julia myscript.jl), then Matplotlib is
executed in non-interactive mode: a plot window is not opened until
you run show() (equivalent to plt.show() in the Python examples).
See the docs linked above for further reference.

Is there any 2D plotting library compatible with pypy?

I am a heavy user of jupyter notebook and, lately, I am running it using pypy instead of python to get extra speed. It works perfectly but I am missing matplotlib so much. Is there any decent 2D plotting library compatible with pypy and jupyter notebook? I don't need fancy stuff, scatter, line and bar plots would be more than enough.
Bokeh is working fairly good with pypy. The only problem I have encountered is linked to the use of numpy.datetime64 that is not yet supported by pypy. Fortunately it is enough to monkey-patch bokeh/core/properties.py and bokeh/util/serialization.py to pass in case of datetime64 reference.
I did it in this way:
bokeh/core/properties.py
...
try:
import numpy as np
datetime_types += (np.datetime64,)
except:
pass
...
and
bokeh/util/serialization.py
...
# Check for astype failures (putative Numpy < 1.7)
try:
dt2001 = np.datetime64('2001')
legacy_datetime64 = (dt2001.astype('int64') ==
dt2001.astype('datetime64[ms]').astype('int64'))
except:
legacy_datetime64 = False
pass
...
And managed to get nice looking plots in jupyter using pypy.

matplotlib configuration for inline backend in jupyter notebook

I'd like to learn how to configure the defaults for matplotlib using the inline backend in jupyter notebook. Specifically, I'd like to set default 'figure.figsize’ to [7.5, 5.0] instead of the default [6.0, 4.0]. I’m using jupyter notebook 1.1 on a Mac with matplotlib 1.4.3.
In the notebook, using the macosx backend, my matplotlibrc file is shown to be in the standard location, and figsize is set as specified in matplotlibrc:
In [1]: %matplotlib
Using matplotlib backend: MacOSX
In [2]: mpl.matplotlib_fname()
Out[2]: u'/Users/scott/.matplotlib/matplotlibrc'
In [3]: matplotlib.rcParams['figure.figsize']
Out[3]:[7.5, 5.0]
However, when I use the inline backend, figsize is set differently:
In [1]: %matplotlib inline
In [2]: mpl.matplotlib_fname()
Out[2]: u'/Users/scott/.matplotlib/matplotlibrc'
In [3]: matplotlib.rcParams['figure.figsize']
Out[3]:[6.0, 4.0]
In my notebook config file, ~/.jupyter/jupyter_notebook_config.py, I also added the line
c.InlineBackend.rc = {'figure.figsize': (7.5, 5.0) }
but this had no effect either. For now I’m stuck adding this line in every notebook:
matplotlib.rcParams['figure.figsize']=[7.5, 5.0]
Is there any way to set the default for the inline backend?
The Jupyter/IPython split is confusing. Jupyter is the front end to kernels, of which IPython is the defacto Python kernel. You are trying to change something related to matplotlib and this only makes sense within the scope of the IPython kernel. Making a change to matplotlib in ~/.jupyter/jupyter_notebook_config.py would apply to all kernels which may not make sense (in the case of running a Ruby/R/Bash/etc. kernel which doesn't use matplotlib). Therefore, your c.InlineBackend.rc setting needs to go in the settings for the IPython kernel.
Edit the file ~/.ipython/profile_default/ipython_kernel_config.py and add to the bottom: c.InlineBackend.rc = { }.
Since c.InlineBackend.rc specifies matplotlib config overrides, the blank dict tells the IPython kernel not to override any of your .matplotlibrc settings.
If the file doesn't exist, run ipython profile create to create it.
Using Jupyter on windows at least, I was able to do it using something very much like venkat's answer, i.e.:
%matplotlib inline
import matplotlib
matplotlib.rcParams['figure.figsize'] = (8, 8)
I did this to square the circle, which had been rather eliptical up to that point. See, squaring the circle is not that hard. :)
Note that the path of ipython_kernel_config.py differs if you run ipython from a virtual environment. In that case, dig in the path where the environment is stored.
Use figsize(width,height) in the top cell and it changes width of following plots
For jupyter 5.x and above with IPython kernels, you can just override particular keys and leave the rest by putting things like this, with your desired figsize in your ~/.ipython/profile_default/ipython_kernel_config.py:
c = get_config()
c.InlineBackend.rc.update({"figure.figsize": (12, 10)})

Julia pyplot from script (not interactive)

I just installed PyPlot in Julia. It's working fine when I run it from julia's interactive environment. But when I make a .jl script an run from bash the plot graphics does not displays.
I'm familiear with matplotlib (pylab) where show() command is used to view the figures. I probably don't undestand the readme of PyPlot here https://github.com/stevengj/PyPlot.jl
You can get the current figure as a Figure object (a wrapper around
matplotlib.pyplot.Figure) by calling gcf(). The Figure type supports
Julia's multimedia I/O API, so you can use display(fig) to show a
fig::PyFigure
If I run this script:
using PyPlot
x = linspace(0,2*pi,1000); y = sin(3*x + 4*cos(2*x));
plot(x, y, color="red", linewidth=2.0, linestyle="--")
title("A sinusoidally modulated sinusoid")
fig1 = gcf()
display(fig1)
I get no graphics on the screen, just text output with address of the figure object
$ julia pyplottest.jl
Loading help data...
Figure(PyObject <matplotlib.figure.Figure object at 0x761dd10>)
I'm also not sure why it take so long time and what "Loading help data..." does mean
if I run the same script from inside of Julia evironment using include("pyplottest.jl") the plot does shows fine
display only works if you are running an environment that supports graphical I/O, like IJulia, but even there you don't really need to call it directly (the plot is displayed automatically when an IJulia cell finishes executing).
You can do show() just like in Python. However, PyPlot loads Matplotlib in interactive mode, with the GUI event loop running in the background, so show() is non-blocking and doesn't really do anything. One option is to just do
using PyPlot
x = linspace(0,2*pi,1000); y = sin(3*x + 4*cos(2*x));
plot(x, y, color="red", linewidth=2.0, linestyle="--")
title("A sinusoidally modulated sinusoid")
print("Hit <enter> to continue")
readline()
to pause.
If you just want to do non-interactive Matplotlib, you don't need the PyPlot package at all. You can just do:
using PyCall
#pyimport matplotlib.pyplot as plt
x = linspace(0,2*pi,1000); y = sin(3*x + 4*cos(2*x));
plt.plot(x, y, color="red", linewidth=2.0, linestyle="--")
plt.title("A sinusoidally modulated sinusoid")
plt.show()
and the show() command will block until the user closes the plot window.
(Possibly I should add an option to PyPlot to load it in non-interactive mode.)
If you are not in REPL or interactive mode (i.e. using sublime like me) then you have to add plt[:show]() to see the plot.
I asked the same question a while ago:
https://groups.google.com/forum/#!topic/julia-users/A2JbZMvMJhY