Draw matplotlib plot to PNG in Jupyter when inline matplotlib is enabled - python

I am drawing a confusion matrix heatmap in Jupyter using code similar to the example here using imshow
Matplotlib is set to draw plots inline.
This works fine for outputting to the cell in the notebook, but I want to not output to the cell but instead get PNG data (ideally raw, not saved to a file) in this case only, not in general (in general I want matplotlib to display inline).
I'm not quite sure how to do that; examples I've seen seem to be global in nature (e.g. calling matplotlib.use() before importing pyplot).
Is this possible? How?

A simple way to not display the plot inline, is to use plt.close() at the end of the cell.
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot([1,2,3],[1,2,3])
plt.savefig("image.png")
plt.close()

Turn off interactive mode:
plt.ioff()
To reactivate inline images, use
plt.ion()
%matplotlib inline
To save the PNG image as bytes, but not to a file, pass a file-like io.BytesIO object to plt.savefig instead of a file:
import io
data = io.BytesIO()
plt.savefig(data)

Related

matplotlib save plot instead of displaying

I am using python on a linux shell and trying to save plot instead of displaying (displaying plot window leads to an error). I looked at question Save plot to image file instead of displaying it using Matplotlib, but didn't help. Here is my code:
import matplotlib.pyplot as plt
#
# list3 is list of data
plt.hist(list3, bins=10)
plt.xlabel('X')
plt.ylabel('Y')
fig.savefig('plot.png')
The problem is figure window is appearing even though I don't call plt.figure(). Is there any way to suppress graphical figure window and instead save plot to the file?
plt.savefig('plot.png') saves the png file for me. May be you need to give full path for the file

plt.ioff() isn't working. How do I plot several different graphs

plt.ioff()
for i in range(0,len(variableList)):
graph = lag1['VDC'].rolling(window=24).corr(other=lag1[variableList[i]])
plt.title(variableList[i])
plt.plot(graph)
plt.axhline(y=0)
plt.savefig(variableList[i])
I want to plot several different independent graphs. The default is in interactive mode where each new graph is plotted on the previous one. I read the document and found that I need to use plt.ioff(). However adding this line doesn't change anything.
If you try the example in non-interactive example, Usage Guide, the output is a set of three graphs indeed. Furthermore, plt.ioff() doesn't work if you set %matplotlib inline.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.ioff()
for i in range(3):
plt.plot(np.random.rand(10))
plt.show()
However, it saves plots with lines accumulated if you use plt.savefig.
%matplotlib inline
plt.ioff()
for i in range(3):
plt.plot(np.random.rand(10))
plt.savefig(f'{i}.png')
Also, it doesn't work if:
%matplotlib auto
plt.ioff()
for i in range(3):
plt.plot(np.random.rand(10))
plt.show()
So, for non-interactive figures, you should always use object-oriented (OO) style to avoid such issues:
%matplotlib auto
plt.ioff()
for i in range(3):
fig, ax = plt.subplots()
ax.plot(np.random.rand(10))
fig.savefig(f'{i}.png')
The interactive mode is used to obtain an event loop while continuiung the execution of the script. This can be useful to update a plot at several different points in a script, for doing quick animations or for working from within the console.
The interactive mode has nothing to do with new figures being created. I.e. you can have several figures or only one figure, both with interactive mode on or off.
To obtain a new figure in pyplot use
plt.figure()
pyplot commands executed after that will apply to this new figure.
The pyplot tutorial has a chapter on Working with multiple figures and axes, where this is explained in detail.

matplotlib not displaying image on Jupyter Notebook

I am using ubuntu 14.04 and coding in jupyter notebook using anaconda2.7 and everything else is up to date . Today I was coding, every thing worked fine. I closed the notebook and when I reopened it, every thing worked fine except that the image was not being displayed.
%matplotlib inline
import numpy as np
import skimage
from skimage import data
from matplotlib import pyplot as plt
%pylab inline
img = data.camera()
plt.imshow(img,cmap='gray')
this is the code i am using, a really simple one but doesn't display the image
<matplotlib.image.AxesImage at 0xaf7017ac>
this is displayed in the output area
please help
You need to tell matplotlib to actually show the image. Add this at the end of your segment:
plt.show()
To show image in Jupyter Notebook by matplotlib, one should use the %matplotlib inline magic command and plt.show().
As for your code, adding plt.show() after plt.imshow() expression will make the image shown.
If using the inline backend, you just need to call plt.show().
If you are using the notebook backend (%matplotlib notebook), then you should call plt.figure() before plt.imshow(img). This is especially important if you wish to use interactive figures!
change kernel from xpython to original python kernel

SVG rendering issues using iPython inline plots

when I use inline plots in iPython (QtConsole), the first plot looks (more or less) fine, but then it gets weirder and weirder. When I plot something several times (so plot, see it displayed, plot again, see output etc.), it looks like it is being overlaid with the skewed previous picture. So after plotting a diagonal line (x=y) 4 times in a row I get something like this
If i right click and export it as svg everything looks good
(Exported PNG picture remains wrecked as the first one).
I guess the problem is similar to https://github.com/ipython/ipython/issues/1866, but I didn't got the upshot of the discussion (it got too technical and complicated for me to follow).
Is there any solution or work around for this issue?
I'm using
python 2.7
matplotlib 1.4.1
IPython 2.1.0
Here is a working example:
%matplotlib inline
% config InlineBackend.figure_format = 'svg'
import matplotlib.pyplot as plt
a=range(10)
fig,ax=plt.subplots()
ax.plot(a,a)
ax.axis('off')
if you remove plt.axis('off') line, weird things happen only outside of the axis box.
P.S. Originally I encountered this problem in connection with drawing graphs with networkx. If I use draw from networkx this problem does not occur. If I use draw_networkx, same as described above happens. That might point to the core of the problem... I'm trying to figure out what line of code makes one work better than the other...
After tinkering around with the draw and draw_networkx functions from networkx module, I found the workaround which makes the difference between draw and draw_networkx in this case.
Adding fig.set_facecolor('w') overlays whatever is in the background, so the new plots are started with a white sheet (but not a blank one, I guess).
So new working example is:
%matplotlib inline
% config InlineBackend.figure_format = 'svg'
import matplotlib.pyplot as plt
a=range(10)
fig,ax=plt.subplots()
fig.set_facecolor('w')
ax.plot(a,a)
ax.axis('off')

Difference between plt.draw() and plt.show() in matplotlib

I was wondering why some people put a plt.draw() into their code before the plt.show(). For my code, the behavior of the plt.draw() didn't seem to change anything about the output. I did a search on the internet but couldn't find anything useful.
(assuming we imported pyplot as from matplotlib import pyplot as plt)
plt.show() will display the current figure that you are working on.
plt.draw() will re-draw the figure. This allows you to work in interactive mode and, should you have changed your data or formatting, allow the graph itself to change.
The plt.draw docs state:
This is used in interactive mode to update a figure that has been altered using one or more plot object method calls; it is not needed if figure modification is done entirely with pyplot functions, if a sequence of modifications ends with a pyplot function, or if matplotlib is in non-interactive mode and the sequence of modifications ends with show() or savefig().
This seems to suggest that using plt.draw() before plt.show() when not in interactive mode will be redundant the vast majority of the time. The only time you may need it is if you are doing some very strange modifications that don't involve using pyplot functions.
Refer to the Matplotlib doc, "Interactive figures" for more information.

Categories