Turning off specgram auto-plotting in Jupyter notebook - matplotlib

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.

Related

How to plot julia inline when using Jupyter in vscode?

I am trying to use Jupyter for Julia in vscode:
using PyPlot
a = [1,2]
b = [2,3]
fig=figure(1)
PyPlot.plot(a, b, linewidth=1)
PyPlot.scatter(a, b)
show()
When I run this a new window will pop up. What I want to do is to prevent it to pop up and see the picture below my codes. After doing some search it seems in Python you can solve it by %matplotlib inline, but how do I sovle it in Julia?
Try gcf() instead of show.
gcf yields the current PyPlot Figure object and it will be automatically rendered by Jupyter:

Accessing backend specific functionality with Julia Plots

Plots is simple and powerful but sometimes I would like to have a little bit more control over individual elements of the plot to fine-tune its appearance.
Is it possible to update the plot object of the backend directly?
E.g., for the default pyplot backend, I tried
using Plots
p = plot(sin)
p.o[:axes][1][:xaxis][:set_ticks_position]("top")
but the plot does not change. Calling p.o[:show]() afterwards does not help, either.
In other words: Is there a way to use the PyPlot interface for a plot that was initially created with Plots?
Edit:
The changes to the PyPlot object become visible (also in the gui) when saving the figure:
using Plots
using PyPlot
p = Plots.plot(sin, top_margin=1cm)
gui() # not needed when using the REPL
gca()[:xaxis][:set_ticks_position]("top")
PyPlot.savefig("test.png")
Here, I used p.o[:axes][1] == gca(). One has to set top_margin=1cm because the plot area is not adjusted automatically (for my actual fine-tuning, this doesn't matter).
This also works for subsequent updates as long as only the PyPlot interface is used. E.g., after the following commands, the plot will have a red right border in addition to labels at the top:
gca()[:spines]["right"][:set_color]("red")
PyPlot.savefig("test.png")
However, when a Plots command like plot!(xlabel="foo") is used, all previous changes made with PyPlot are overwritten (which is not suprising).
The remaining question is how to update the gui interactively without having to call PyPlot.savefig explicitly.
No - the plot is a Plots object, not a PyPlot object. In your specific example you can do plot(sin, xmirror = true).
I'm trying to do the same but didn't find a solution to update an existing plot. But here is a partial answer: you can query information from the PyPlot axes object
julia> Plots.plot(sin, 1:4)
julia> Plots.PyPlot.plt[:xlim]()
(1.0,4.0)
julia> Plots.plot(sin, 20:24)
julia> ax = Plots.PyPlot.plt[:xlim]()
(20.0,24.0)
and it gets updated.

Julia: How to save a figure without plotting/displaying it in PyPlot?

I am using the PyPlot package in Julia to generate and save several figures. My current approach is to display the figure and then save it using savefig.
using PyPlot
a = rand(50,40)
imshow(a)
savefig("a.png")
Is there a way to save the figure without having to first display it?
Are you using the REPL or IJulia?
If you close the figure then it won't show you the plot. Is that what you want?
a = rand(50,40)
ioff() #turns off interactive plotting
fig = figure()
imshow(a)
close(fig)
If that doesn't work you might need to turn off interactive plotting using ioff() or change the matplotlib backend (pygui(:Agg)) (see here: Calling pylab.savefig without display in ipython)
Remember that most questions about plotting using PyPlot can be worked out by reading answers from the python community. And also using the docs at https://github.com/JuliaPy/PyPlot.jl to translate between the two :)
close() doesn't require any arguments so you can just call close() after saving the figure and create a new figure
using PyPlot
a = rand(50,40)
imshow(a)
savefig("a.png")
# call close
close()

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

IPython plotting inline not showing

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.