Misterious appearance of Plots MIME output in Jupyterlab

I am puzzled by why a plot is shown in Jupyterlab despite I take all precautions for it not to be, when I call savefig().

In short, if I do

using Plots

plot(range, range.^2);

in Jupyterlab, then the plot is shown, despite I put semicolons, and I set the output of the cell to be nothing.

If I do

plot(range, range.^2);

no plot is shown, as desired.

If I do

plot(range, range.^2);

and in a separate cell


no plot is shown!

Furthermore, if I set “fmt = :svg” to get SVG plots by default, I do get SVG plots when using “plot()” but savefig() always produces PNG plots, and there is no way to silence this production in the Jupyterlab cell output.

There should be a weird interaction between Plots and Jupyterlab. I am triying to understand what happens but I try also to see if anybody more expert than me has any insight. I have collected my tests in this notebook: https://gist.github.com/3ffefb4183fe026d5572baecdcde8808 .

The behaviour I observe is due to the fact that I am using PyPlot as backend, savefig() invokes the appropriate code in PyPlot to save a plot, preparing a “figure”, and PyPlot sets the following post-execution hook for any IJulia cell:


apparently, the preparation of a figure in PyPlot code for saving a plot sets up something that is treated by the hook as something to be shown in the Jupyter cell output.

In order to disable this behaviour, a savefigsilent() function can be defined as follows:

function savefigsilent(plt, fn::AbstractString)
  ##--- brutally close all pending figures prepared for display according to PyPlot
  for manager in PyPlot.Gcf."get_all_fig_managers"()
    f = manager."canvas"."figure"
    if f.number ∉ PyPlot.withfig_fignums
      ##--- close only figures not suspended for further handling
  savefig(plt, fn)
savefigsilent(fn::AbstractString) = savefigsilent(current(), fn::AbstractString)