Include output from %matplotlib notebook backend as SVG in ipynb - python

This answer from a few years ago shows how you can make jupyter notebook create graphs as svg. The solution is to tell the InlineBackend to use svg as output.
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
plt.plot(...)
This will cause all images to be in svg format inside the notebook as well as in the produced ipynb file; the file will have a line like
"data": { "image/svg+xml": [ "<?xml .....
in it.
The problem is now that this does not work if the %matplotlib notebook backend is used. %config InlineBackend does not change anything for the notebook backend, hence the output file contains a PNG image
"data": { "text/html": [ "<img src=\"data:image/png;base64,iVBORw0....
So the question is: How do I get the ipynb file to include a static version of the plot that is created with the %matplotlib notebook backend as SVG image?
There is a small comment by #mark jay from one month ago, who wanted to do exactly what I would like to do now, but there is no answer or hint to that comment.
In my code I have plotted directly from the dataframe:
%matplotlib notebook
import pandas as pd
df = pd.read_sql(sql1, connection)
...
...
df.plot(subplots=True, kind='bar')
This functions perfectly well without importing matplotlib.pyplot but it also can't be coerced to create the graphic as an svg. I suppose if the base case would work, I could modify the plotting code so it did not involve pandas or dataframes.

Since apparently even after a bounty period noone was able to provide a solution, a workaround may be the following.
Create you notebook with %matplotlib notebook. Once you're satisfied with the result, save it.
Use a copy of it and replace %matplotlib notebook with
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
Rerun the complete notebook. Save the result.
Open the resulting ipynb file in a text editor and replace the previous two lines again with %matplotlib notebook.
The final result will be a ipynb with svg images. But once opened and run, it will use the notebook backend for figure creation.

From whatI understand from reading about matplotlib backends, nbagg, which is called using %matplotlib notebook uses the Agg (Anti-Grain Geometry) render which is not capable of rendering vector graphics. Unfortunately this is the only out of the box way of using an interactive inline backend for Jupyter.
Docs Link https://matplotlib.org/faq/usage_faq.html#what-is-interactive-mode
Similar Answer How to make matplotlibs nbagg backend generate SVGs?
If you don't need the interactivity just keep use
import pandas as pd
from IPython.display import SVG, display
from numpy import ndarray
def svg_add(chart, size=(4,4), dpi=100):
"""Takes a chart, optional tuple of ints for size, int for dpi
default is 4 by 4 inches with 100 dpi"""
if type(chart) == ndarray:
fig = chart[0].get_figure()
fig.set_size_inches(size)
fig.savefig("mybar.svg", dpi=dpi)
display(SVG(filename='mybar.svg'))
else:
fig = chart.get_figure()
fig.set_size_inches(size)
fig.savefig("mybar.svg", dpi=dpi)
display(SVG(filename='mybar.svg'))
then
df = pd.DataFrame([[2,5]],columns=['a','b'])
bar_chart = df.plot(subplots=False, kind='bar')
svg_add(chart=bar_chart,size=(3,3),dpi=100)
#or
#svg_add(bar_chart,(3,3),100)

Related

Why is there a difference in using method ".plot()" between jupyter notebook and pycharm?

I'm following pandas tutorial1 with pycharm.
Tutorial describes how to use method '.plot()' with jupyter-notebook as
enter image description here
But if I write this code in pycharm, nothing is shown.
if I change code as below, it works same with image
import pandas as pd
import matplotlib.pyplot as plt
air_quality = pd.read_csv("air_quality_no2.csv", index_col=0,
parse_dates=True)
plt.plot(air_quality)
plt.show()
Why is there a difference in using method ".plot()" between jupyter notebook and pycharm?
Thanks.

Programmatically making and saving plots in (I)python without rendering them on the screen first

Here's a dummy script that makes three plots and saves them to PDF.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame({"A":np.random.normal(100),
"B":np.random.chisquare(5, size = 100),
"C":np.random.gamma(5,size = 100)})
for i in df.columns:
plt.hist(df[i])
plt.savefig(i+".pdf", format = "pdf")
plt.close()
I'm using spyder, which uses IPython. When I run this script, three windows pop at me and then go away. It works, but it's a little annoying.
How can I make the figures get saved to pdf without ever being rendered on my screen?
I'm looking for something like R's
pdf("path/to/plot/name.pdf")
commands
dev.off()
inasmuch as nothing gets rendered on the screen, but the pdf gets saved.
Aha. Partially based on the duplicate suggestion (which wasn't exactly a duplicate), this works:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame({"A":np.random.normal(100),
"B":np.random.chisquare(5, size = 100),
"C":np.random.gamma(5,size = 100)})
import matplotlib
old_backend = matplotlib.get_backend()
matplotlib.use("pdf")
for i in df.columns:
plt.hist(df[i])
plt.savefig(i+".pdf", format = "pdf")
plt.close()
matplotlib.use(old_backend)
Basically, set the backend to something like a pdf device, and then set it back to whatever you're accustomed to.
I am referring you to this StackOverflow answer which cites this article as an answer. In the SO answer they also suggest plt.ioff() but are concerned that it could disable other functionality should you want it.

mplleaflet in Jupyter - avoid whitespace with notebook mode?

mplleaflet works great with '%matplotlib inline' mode in the Jupyter Notebook, but when enabling '%matplotilib notebook' mode, there's a big chunk of whitespace between the cell and the map. Can this be avoided?
Code:
import matplotlib.pyplot as plt
import mplleaflet
%matplotlib notebook
#some latitudes bracketing seattle
lats = [47.5062,47.7062]
#longitude
lons = [-122.3321]*len(lats)
fig,ax=plt.subplots(figsize=(8,8))
ax.scatter(lons, lats, alpha=0) #invisible data points, just to scale the map
mplleaflet.display(fig=fig)
The output looks like this:
The problem is that there is a figure created which is supposed to be shown in the notebook. However, you do not want to show the mplleaflet figure as an interactive figure with the %matplotlib notebook backend.
One idea is to not use the %matplotlib notebook such that the area where the figure mplleaflet figure would be placed is not filled with the unused figure.
Alternatively use %%capture in order to suppress the output when using %matplotlib notebook. Then call mplleaflet.display in a new non-captured cell:

Blank image when saving an imshow matplotlib figure in iPython notebook

I'm using iPython notebook w/ matplotlib to display a bunch of images inline, but now it's come time to save a number of these images (think for-loop, i.e. not a small number of images to save). My issue seems to be something to do with how I'm using iPython since I could do this alright when my script was a standalone.
%matplotlib inline
import matplotlib.pyplot as plt
....
grid_z2 = griddata(....)
fig = plt.figure()
ax = fig.add_axes([1,1,1,1])
plt.imshow(grid_z2.transpose(),origin='Lower')
plt.colorbar()
plt.draw()
fig.savefig('slicemap.png')
I have also tried plt.savefig(), fig1 = plt.gcf() before plt.imshow then trying to save fig1... always every single time a blank file.
Any suggestions?

displaying charts from python executables in shell

I'm using python 2.7 on Ubuntu to draw charts from text files containing data.
My point is, when using python executables in shell, I have no problem recording plots, but if I want them shown on my screen instead I have to go through the graphic interface. If possible, I would very much like to skip that part and get a dynamic display that I can interact with (as if I were to run my script from a python shell)!!
a MWE of what i'm doing is :
MWE
import numpy as np
import matplotlib.pyplot as plt
with open('filename','r') as myfile:
DATA = np.genfromtxt(myfile,unpack=True)
fig = plt.figure()
... my plot configuration ...
plt.savefig("image_name"+'.png')
plt.close()
end of MWE
Using this script image_name.png appears in my repertory. I tried replacing the last 2 lines with plt.plot() and plt.draw() but nothing happened.
Many thanks!
Michel
(edited)

Categories

Resources