Exporting jupyter notebook to pdf with offline plotly graph; missing graphs - python

I am trying to create pdf export of my lesson plans and I use plotly offline for the graphs. In a MWE below, the plot will display in the Jupyter Notebook but will not show up when I export to pdf. I export using File-->Download as-->PDF via Latex (.pdf).
I'd like to make a pdf instead of using html. I understand it might take an extra step to convert an html export to pdf, but I was just wondering if there was a more direct route (a code modification?) that would allow me to export directly through File-->Download as-->PDF via Latex (.pdf)
from plotly.offline import download_plotlyjs, init_notebook_mode, iplot
init_notebook_mode(connected=True)
import plotly.graph_objs as go
data = [go.Scatter(
x=[1, 2, 3],
y=[3, 2, 1])
]
iplot(data)

You need to specify the appropriate Default Renderer (or Renderers, if you want to visualize it in the Notebook and also when exporting to PDF using the File-->Download as-->PDF via Latex (.pdf) option you mentioned).
I have been struggling with this myself for some hours too, but the setup that ended up working for me is the following:
import plotly.io as pio
pio.renderers.default = "notebook+pdf" # Renderer for Notebook and HTML exports + Renderer for PDF exports
# init_notebook_mode(connected=True) # Do not include this line because it may not work
Note that you can concatenate as many Renderers as you want using the + symbol, and Plotly will magically know when to use each of them.

I think because plotly graphs are svg objects and generated by javascript, I dont have export to PDF working in my jupyter notebook, so I was unable to check and confirm my answer.
Plotly offline does not have show as image, you can use plotly online to do this, its free to generate graphs,
You need to create an online account, also you need to paste the username and API key from plotly website (API key can be found in settings).
Note: please check in plotly if the plots are shared in public or private, I am not responsible for your plots becoming public.
Anyway this will give you an image output of the graph, and you can export it to PDF
Code:
import plotly
import plotly.graph_objs as go
plotly.plotly.sign_in('<<username goes here>>', '<<api key goes here>>')
trace = go.Bar(x=[2, 4, 6], y= [10, 12, 15])
data = [trace]
layout = go.Layout(title='A Simple Plot', width=800, height=640)
fig = go.Figure(data=data, layout=layout)
plotly.plotly.image.save_as(fig, filename='a-simple-plot.png')
from IPython.display import Image
Image('a-simple-plot.png')

I don't have a solution for the exact original problem above. However, if you wish to consider the .html format, here is a nice solution that worked for me. After all, my goal was just to share the notebook with people who didn't have jupyter installed.
The conversion to .html is performed with plotlyhtmlexporter.
Here is a piece of code you can copy-paste:
pip install plotlyhtmlexporter
jupyter nbconvert --to plotlyhtml mynotebook.ipynb
You might then want to try and save (print) the .html from your browser as a .pdf, but I think it would be equivalent to just printing the original notebook to .pdf. As I say, in my case, having a jupyter-independent .html file was enough.

A bit easier solution is to use image_bytes = fig.to_image(format='png') and than display using Image(image_bytes), but firstly you should install orca, and pip3 install psutil requests
example:
fig = go.Figure()
""" here goes some code to draw """
image_bytes = fig.to_image(format='png', , width=1200, height=700, scale=1) # you can use other formats as well (like 'svg','jpeg','pdf')
#instead of using fig.show()
from IPython.display import Image
Image(img_bytes)
You can read more here
Than you can convert it with File -> Download as -> PDF or using terminal jupyter nbconvert --to pdf <notebook_name>.ipynb

Just use this and download the notebook as PDF via HTML. Also you need to pip install kaleido first.
import plotly.io as pio
pio.kaleido.scope.default_format = "png"

Related

Plotly: How to embed a fully interactive Plotly figure in Excel?

I'm trying to embed an interactive plotly (or bokeh) plot into excel.
To do this I've tried the following three things:
embed a Microsoft Web Browser UserForm into excel, following:
How do I embed a browser in an Excel VBA form?
This works and enables both online and offline html to be loaded
creating a plotly html
'''
import plotly
import plotly.graph_objects as go
x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
y = [i**2 for i in x]
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=x, mode='markers', name="y=x", marker=dict(color='royalblue', size=8)))
fig.add_trace(go.Scatter(x=x, y=y, name="y=x^2", line=dict(width=3)))
plotly.offline.plot(fig, filename='C:/Users/.../pythonProject/test1.html')
repointing the webbrowser object in excel using .Navigate to the local plotly.html. Banner pops up with
".... restricted this file from showing active content that could access your computer"
clicking on the banner, I run into this error:
The same HTML can be opened in a browser.
Is there any way to show interactive plots in excel?
Finally, I have managed to bring the interactive plot to excel after a discussion from Microsoft QnA and Web Browser Control & Specifying the IE Version
To insert a Microsoft webpage to excel you have to change the compatibility Flag in the registry editor
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\16.0\Common\COM Compatibility{8856F961-340A-11D0-A96B-00C04FD705A2}
Change the DWord 0 instead of 400
Now you can insert the web browser object to excel, Step by step details are here
Edit the HTML File generated from plotly manually by adding a tag for Using the X-UA-Compatible HTML Meta Tag
Originally generated HTML file from plotly looks like this
<html>
<head><meta charset="utf-8" /></head>
<body>
Modified HTML with browser compatibility
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
After this, I can able to view the interactive plot in excel also able to do the interactions same as a web browser
Macro used:
Sub Button4_Click()
ActiveSheet.WebBrowser1.Navigate "file:///C:/Users/vignesh.rajendran/Desktop/test5.html"
End Sub
As mentioned by #jerlich, Excel blocks javascript. You should try the workaround they linked if you want full interactivity.
If you want at least some degree of controllability or interactivity, try using xlwings. With excel buttons, you can still have some communication between Excel and Python (including reading data and sending graphs).
The limitations are:
Only being able to use data entries and buttons, instead of the default plotly interactive features. Many could be replicated, but it would be more work.
It will only work on a computer you can set up your python script on (however, it looks like xlwings pro allows you to store your program inside the file)
It seems you will need to pass plotly graphs by saving and then adding the figure, because directly passing them requires xlwings pro. Direct passing without pro is possible with MatPlotLib.
Plotly guide to making interactive(ish) graphs
xlwings docs on MatPlotLib and Plotly graphs
Interactive plots require javascript to work. Excel, for security reasons, blocks that javascript. You can put a static image easily into excel.
The challenge of including javascript in excel has been addressed in this question: How can I use JavaScript within an Excel macro?
I like your question! And I'd wish I could give you a better answer, but It seems that the only way you can achieve anything remotely resembling an interactive plotly plot would be to use pyxll and follow the steps outlined under Charts and plotting / Plotly including a plot function like this:
from pyxll import xl_func, plot
import plotly.express as px
#xl_func
def plotly_plot():
# Get some sample data from plotly.express
df = px.data.gapminder()
# Create a scatter plot figure
fig = px.scatter(df.query("year==2007"),
x="gdpPercap", y="lifeExp",
size="pop", color="continent",
log_x=True, size_max=60)
# Show the figure in Excel using pyxll.plot
plot(fig)
This will produce the following plot:
Alas, this will not be a fully interactive plotly plot like we all know and love, since it's also stated on the very same page that:
The plot that you see in Excel is exported as an image so any
interactive elements will not be available. To make a semi-interactive
plot you can add arguments to your function to control how the plot is
done and when those arguments are changed the plot will be redrawn.
But as far as I know this is as close as you'll get to achieving what you're seeking in your question. If you're not limited to Excel, but somehow limited to the realm of Microsoft, one of the commenters mentioned that you can unleash a fully interactive plotly plot in PowerBI. If that is an option, you should take a closer look at Is it possible to use R Plotly library in R Script Visual of Power BI?. This approach uses R though...

Python can i present bokeh plotting outside jupyter notebook?

I've been using bokeh to plot data on a map using bokeh.
Is there a way to work with this library outside jupyter notebook?
Something like in Pychram and saving the plot to HTML file.
Bokeh can generate complete HTML pages for Bokeh documents using the file_html() function. you can refer Embedding Plots and Apps for more detail.
from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import file_html
plot = figure()
plot.circle([1,2], [3,4])
html = file_html(plot, CDN, "my plot")

Plotly doesn't show charts on Spyder (Python 3.5)

I'm trying to learn how to plot a Heat Map on Python
Therefore I've download the library Plotly and I'm very new at it
I was trying to see if I could get the example code of plotly to work, but I failed, because I didn't have an account. I created my account and run the code
import plotly
#plotly.tools.set_credentials_file(username='julirov',
api_key='$$$$$$$$')
import plotly.plotly as py
import plotly.graph_objs as go
trace = go.Heatmap(z=[[1, 20, 30],[20, 1, 60],[30, 60, 1]])
data = [trace]
py.iplot(data, filename='basic-heatmap')
I made my account (with my api_key too) and when I run the code, I've got this message:
High five! You successfully sent some data to your account on
plotly. View your plot in your browser at
https://plot.ly/~julirov/0 or inside your plot.ly account where it
is named 'basic-heatmap'
The thing is: I want to see the chart on my Spyder, and not on a Website
Is that possible with Plotly? Or do I have to use another package?
Thank you!
You can use plotly offline (no account needed). Spyder runs the code to generate a local plot (in an HTML file) which is then viewed via your web browser:
import plotly.graph_objects as go
from plotly.offline import plot
trace = go.Heatmap(z=[[1, 20, 30],[20, 1, 60],[30, 60, 1]])
data = [trace]
plot(data, filename='basic-heatmap.html')
You use Spyder to develop the plot (file), and the browser to view it.
The issue may have to do with the renderer. To set the renderer in spyder, you can use the following:
import plotly.io as pio
pio.renderers.default = "svg"
Anaconda may not have Orca installed natively, so in the Anaconda terminal, you may have to install it:
conda install -c plotly plotly-orca
From there, you can use plotly express to create the heat map (code pulled from here: https://plotly.com/python/heatmaps/). You should not need an account to use plotly express – it will render locally by default.
import plotly.express as px
trace = go.Heatmap(z=[[1, 20, 30],[20, 1, 60],[30, 60, 1]])
data = [trace]
plot(data, filename='basic-heatmap.html')
Heatmap

How to export Bokeh view to Matplotlib?

I have a Flask web app that uses Bokeh to deliver interactive charts. My end goal is to export whatever the current Bokeh view is to Matplotlib (so that I can create a printable pdf file after that). This would include how the current axes look like after the user zooms and pans. Is there a way to export that data so that I can create those Matplotlib charts behind the scenes? (Printing the page directly or printing to pdf results in low-quality and blurred charts.)
Thanks!
No, currently there is no way to export bokeh to matplotlib. Actually you can do it otherway. You can create matplotlib plot, save, and after that you can export matplotlib to bokeh. I think this is the best option. Eventually you can export bokeh plot as png but it still would not solve problem with quality

Bokeh: how to save a file as svg?

I would like to embed a Bokeh plot (from IPython notebook) into my blog as an svg file. Is there currently a way to save the plots as svg's?
I tried to look in the documentation, but it's a little unclear.
This is now possible! From the doc:
from bokeh.io import export_svgs
plot.output_backend = "svg"
export_svgs(plot, filename="plot.svg")

Categories

Resources