saving a sankey to a file from jupyter - python

I have a loop where I want to render some sankeys to .png files.
Checking some docs here:
https://nbviewer.jupyter.org/github/ricklupton/ipysankeywidget/blob/master/examples/Exporting%20Images.ipynb
I would expect sankey.save_svg('test.svg') to work.
From reading those docs, there's a caveat that trying to display and then save won't work, but I'm not trying to display, I just want to save a list of images. However I'm getting the same warnings.warn('No png image available! Try auto_save_png() instead?') error and cannot save.
If I run one line at a time, and return the sankey and let it display in the normal run of a python notebook, things work ok... So it seems there's something that happens when you let the notebook display a sankey that isn't happening when I'm just trying in a loop to render them to files.
from ipywidgets import Layout
from ipysankeywidget import SankeyWidget
def draw_one(use_case, limit=50):
df = Cli.query_paths(use_case=use_case, limit=limit)
layout = Layout(width="2000", height="500")
fpath = f'./data/ignored/images/{use_case}-{limit}.png'
# with or without: .auto_save_png(fpath)
sankey = SankeyWidget(links=df.to_dict('records'), layout=layout)
sankey.save_png(fpath)
cases = [
'INTL',
'PAC',
]
def loop():
for use_case in cases:
print('sk:', use_case)
sk = draw_one(use_case, limit=50)
loop()

Related

Saving graphs to .html using mpld3

I am trying to show a graph using seaborn and mpld3 but in a .html file. When I use the command mpld3.show(), a new window pops and the graph is shown in a local webserver created (like the documentation describes). However, when trying to save it in a .html file, the graph comes empty but I can see some icons like move and zoom avaliable....
With mpld3.show()
sns.set(style="whitegrid")
sns.barplot(x=df.index.tolist(), y=df['Salário'])
mpld3.show()
Graph how its supposed to be:
Trying to save to .html file using save_html():
sns.set(style="whitegrid")
sns.barplot(x=df.index.tolist(), y=df['Salário'])
fig = plt.figure()
mpld3.save_html(fig, "./templates/graph_exp.html")
Bugged graph with working icons
Can someone help me make this graph appear normal saving to a .html file? :)
I am not sure how save_html() works but this is what i use on my flask website.
This solution works if you do not need to save the image.
import base64
import io
pngImage = io.BytesIO()
FigureCanvas(fig).print_png(pngImage) #fig is my matPlotlib instance of Figure()
# Encode PNG image to base64 string
image = "data:image/png;base64,"
image += base64.b64encode(pngImage.getvalue()).decode('utf8')
then in html use:
<img src="{{image}}">

Display a pdf file using colab

I have saved some images of my work in .pdf format using matplotlib, I know this is my fault from the beginning and I should save it directly as image but I did not know that I can not display pdf files on colab. To get these results I need another 10 days which is not good choice for me.
Actually I have found this which express my problem precisely but there was not answer.
It just seems strange to me that using matplotlib I can save pdf files but I can not load them using it again.
I just need to display the pdf file in colab cell ,I have tried:
import subprocess
subprocess.Popen(['myfile.pdf'],shell=True)
and this was the result:
<subprocess.Popen at 0x7f4d6a395978>
another methods as in this page do not work for me
Ok this works for me, maybe there are a simpler solution but for now this works
from pdf2image import convert_from_path
from IPython.display import display, Image
images = convert_from_path("myfile.pdf")
for i, image in enumerate(images):
fname = "image" + str(i) + ".png"
image.save(fname, "PNG")
Image(fname, width=600, height=300)
In a Jupyter notebook / Colab you can simply
from pdf2image import convert_from_path
images = convert_from_path("myfile.pdf")
images[0] # first page
The image will be able to render as the cell output. No need for IPython.display

Plotly figures in jupyter notebook take huge amounts of memory

I may be doing something really stupid, but I've been using plotly offline in my jupyter notebook using
import plotly.offline as py
py.init_notebook_mode(connected=True)
from plotly.graph_objs import *
I'm trying to display a sequence of images that can be navigated with a slider. The entire numpy array with the image data is 50 images x 64 wide x 64 tall.
I put that into the following slider function I pieced together from code I found online. The Figure object itself that's returned is not very large. However, when plotly's iplot is called, the size of my jupyter notebook on disk (as measured by ls -l) is really big - like 15 MB, even though the numpy source data is like 1MB. This becomes unmanageable for larger/multiple figures. Does anyone know what's going on?
def slider_ims(imgs):
imgs = np.flip(imgs,1)
data = [dict(
type='heatmap',
z = imgs[step,:,:],
visible = False,
showscale=False,
xaxis="x",
yaxis="y",
name = 'z = '+str(step)) for step in np.arange(imgs.shape[0])]
data[0]['visible'] = True
steps = []
for i in range(len(data)):
step = dict(
method = 'restyle',
args = ['visible', [False] * len(data)],
label = str(i)
)
step['args'][1][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active = 0,
currentvalue = {"prefix": "Frame: "},
pad = {"t": 50},
steps = steps,
ticklen = 0,
minorticklen = 0
)]
layout = Layout(
sliders = sliders,
font=Font(family='Balto'),
width=800,
height=600,
)
fig=Figure(data=data, layout=layout)
py.iplot(fig)
return fig
You want smaller ipynb files? Don't store output cells.
If you only care about the on-disk size of your notebooks, you could change your Jupyter configuration to disable writing output cells to the ipynb file. This would mean that only your code is saved on disk. Whenever you open a notebook, the output cells will be empty and you need to re-run the notebook to get them. You have to decide whether this fits with how you use notebooks.
You can set this up by editing your jupyter_notebook_config.py configuration file, which is typically located in your home directory under ~/.jupyter (Windows: C:\Users\USERNAME\.jupyter\). If it does not exist yet, this file can be generated from the termial with jupyter notebook --generate-config (more info here).
In this configuration file, you need to add a pre-save hook that strips output cell before saving as described in the documentation:
def scrub_output_pre_save(model, **kwargs):
"""scrub output before saving notebooks"""
# only run on notebooks
if model['type'] != 'notebook':
return
# only run on nbformat v4
if model['content']['nbformat'] != 4:
return
for cell in model['content']['cells']:
if cell['cell_type'] != 'code':
continue
cell['outputs'] = []
cell['execution_count'] = None
c.FileContentsManager.pre_save_hook = scrub_output_pre_save
Bonus benefit: Stripping output cells like this is also a great way to get readable diffs for source control, e.g. git.
Normally, plotly's plot has a big size. Your notebook size increased because you save the plot on your notebook using inline plot (py.iplot).
If you don't want your notebook to be so large, just use the normal plot (py.plot) and save the plot in another file.
You can read the plotly's documentation
In my case, I used as follows to avoid saving the plot along with the notebook. I prefer to save the image as a different page to keep the notebook's size.
import plotly.offline as pyo
pyo.plot(fig, filename="example.html")

Convert SVG/PDF to EMF

I am looking for a way to save a matplotlib figure as an EMF file. Matplotlib allows me to save as either a PDF or SVG vector file but not as EMF.
After a long search I still cannot seem to find a way to do this with python. Hopefully anyone has an idea.
My workaround is to call inkscape using subprocess but this is far from ideal as I would like to avoid the use of external programs.
I'm running python 2.7.5 and matplotlib 1.3.0 using the wx backend.
For anyone who still needs this, I wrote a basic function that can let you save a file as an emf from matplotlib, as long as you have inkscape installed.
I know the op didn't want inkscape, but people who find this post later just want to make it work.
import matplotlib.pyplot as plt
import subprocess
import os
inkscapePath = r"path\to\inkscape.exe"
savePath= r"path\to\images\folder"
def exportEmf(savePath, plotName, fig=None, keepSVG=False):
"""Save a figure as an emf file
Parameters
----------
savePath : str, the path to the directory you want the image saved in
plotName : str, the name of the image
fig : matplotlib figure, (optional, default uses gca)
keepSVG : bool, whether to keep the interim svg file
"""
figFolder = savePath + r"\{}.{}"
svgFile = figFolder.format(plotName,"svg")
emfFile = figFolder.format(plotName,"emf")
if fig:
use=fig
else:
use=plt
use.savefig(svgFile)
subprocess.run([inkscapePath, svgFile, '-M', emfFile])
if not keepSVG:
os.system('del "{}"'.format(svgFile))
#Example Usage
import numpy as np
tt = np.linspace(0, 2*3.14159)
plt.plot(tt, np.sin(tt))
exportEmf(r"C:\Users\userName", 'FileName')
I think the function is cool but inkscape syntax seems not working in my case. I search in other post and find it as:
inkscape filename.svg --export-filename filename.emf
So if I replace -M by --export-filename within the subprocess argument, everything works fine.

How to prevent plotly from plotting automatically

I just discovered plotly and like it so far. I have this code provided by the main website
import plotly.plotly as py
from plotly.graph_objs import *
trace0 = Scatter(
x=[1,2,3,4],
y=[10,15,13,17]
)
trace1 = Scatter(
x=[1,2,3,4],
y=[16,5,11,9]
)
data = Data([trace0, trace1])
unique_url = py.plot(data, filename='basic-line')
I am curious about two things:
1) When I run this code, my browser automatically pops up and shows me the graph. All I want is the url so that I can later embed it in an html file. Is there a way to turn off the feature that opens my browser and shows me the graph?
2) Is there a way to get rid of the 'Play with this data' link?
I have combed through the documentation provided, but have come up empty-handed on these two issues.
To disable pop-ups you could use auto_open=FALSE and try the following
py.plot(data, filename='basic_line', auto_open=False)
py.plot(data, show_link=False) will take that link off (if you are referring to the link that says Export to plot.ly). At least it does using:
import plotly.offline as py. As for the link at the top (when you hover your mouse over the graph), I'm trying to get rid of the Save and edit plot in cloud but only find options for that under the java script version... and that hides the whole bar which has other useful items on it (javascript option is: {displayModeBar: false}). Obviously I am finding the reference to "play with this data" ambiguous. You can see the workaround I wrote here: Adding config modes to Plotly.Py offline - modebar
You can easily remove that Export to plot.ly link in the offline graph.
Open your saved html file in a text editor. and search for. {"showLink": true, "linkText": "Export to plot.ly"}
And change the true value to false.

Categories