Issue with Bokeh AutocompleteInput in jupyter notebook cell - python

I'm using an AutocompleteInput widget in a jupyter notebook. The autocompletion itself is working fine but I have an issue with the output.
Issue circled in red
Is it possible somehow to be able to see the ouput of the autocompletion without having to scroll (which is really not user friendly) ? (resizing the output cell of the notebook, autofiting the cell, option of the AutocompleteInput widet)
this is what i've done at the moment:
input_widget = AutocompleteInput(completions=list(df_competences['libelleCompetence']), title='Chercher une compétence', placeholder='Chercher une compétence', sizing_mode='scale_height', css_classes=['my_autocomplete_class'])
show(input_widget)
I've been looking a lot of possibilities but not founding a way to do this...

In case someone fall on the same issue as me, here is how I manged to fix it:
I'm getting the HTML code generated by bokeh, remove the class used by bokeh and replacing it with my own one. Then, you just need to create your own css class to make the autocompletion output suitable.
Here is the code:
from IPython.display import HTML
input_widget = AutocompleteInput(completions=list(df_competences['libelleCompetence']), title='Chercher une compétence: ', placeholder='Chercher une compétence', sizing_mode='scale_both', css_classes=['my_autocomplete_class'])
script, div = components(input_widget)
div = div.replace('bk-root', 'my_class')
div = div.replace('<div class="my_class"', '<div class="my_class" style="width: 100%; max_height: 500;"')
HTML(script + div)

Add a display HTML command, where you specify the min-height of the displayed suggestion box:
from IPython.core.display import display, HTML
input_widget = AutocompleteInput(completions=list(df_competences['libelleCompetence']), title='Chercher une compétence', placeholder='Chercher une compétence', sizing_mode='scale_height', css_classes=['my_autocomplete_class'])
display(HTML('<style> .bk-root[id] { min-height:100pt } </style>'))
show(input_widget)

Related

How can I hide code and rerun all cells in a jupyter notebook?

I'd like to add some sort of functionality at the beginning of a Jupyter Notebook that hides / shows all cells and reruns all cells. What I'd like to end up with is a set of charts that are refreshed when all cells are re-run.
The details and what I've tried:
The post IPython - Run all cells below from a widget shows how you can add a button to rerun all cells below. And the post How to hide code from cells in ipython notebook visualized with nbviewer?. With this setup in two different cells I end up with this:
When the cells are collapsed it looks like this:
And this works pretty well, but I'm just really curious if it's possible to format the buttons so that they look the same. And maybe it's possible to align them as output from the same cell? I've tried to do just that by having the two snippets in the same cell, but now it seems that the Hide button is overwritten by the Refresh button:
Snippet 1:
from IPython.display import HTML
HTML('''<script>
function code_toggle() {
if (code_shown){
$('div.input').hide('500');
$('#toggleButton').val('Show code')
} else {
$('div.input').show('500');
$('#toggleButton').val('Hide code')
}
code_shown = !code_shown
}
$( document ).ready(function(){
code_shown=false;
$('div.input').hide()
});
</script>
<form action="javascript:code_toggle()"><input type="submit" id="toggleButton" value="Show code"></form>''')
from IPython.display import Javascript, display
from ipywidgets import widgets
def run_all(ev):
display(Javascript('IPython.notebook.execute_cells_below()'))
button = widgets.Button(description="Refresh")
button.on_click(run_all)
display(button)
And now I end up with this:
Output 1:
Does anyone know how to make this a bit more elegant?
I really hope someone is able to provide a better answer, but having tried and failed for a couple of hours, I've found this:
By simply mixing a few parts of the two snippets in the question, I'm able to set up a Refresh button in the same format as the Hide Code buttion:
Ouptput / Notebook View:
But this still requiers two code snippets in two different cells, as well as some test code in a third cell:
Cell / snippet 1:
from IPython.display import HTML
HTML('''<script>
function code_toggle() {
if (code_shown){
$('div.input').hide('500');
$('#toggleButton').val('Display code')
} else {
$('div.input').show('500');
$('#toggleButton').val('Hide Code')
}
code_shown = !code_shown
}
$( document ).ready(function(){
code_shown=false;
$('div.input').hide()
});
</script>
<form action="javascript:code_toggle()"><input type="submit" id="toggleButton" value="Display code"></form>''')
Cell / snippet 2:
HTML('''<script>
</script>
<form action="javascript:IPython.notebook.execute_cells_below()"><input type="submit" id="toggleButton" value="Refresh"></form>''')
Cell / snippet 3:
try: x
except NameError: x = None
if x is None:
x = 0
print(x)
else:
x = x + 1
print(x)
However, I'm still not able to display the two buttons beautifully side by side, and the display flickers when I hit Refresh.

Ipywidget Gridbox no output displayed - PYTHON JUPYTER NOTEBOOK

I've been going over the Ipywidgets documentation, and found that when ever I use a GridBox, there isn't any output in Jupyter
notebook.
https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20Styling.html#Shorthand-CSS-properties
Example with this snippet of code below.
from ipywidgets import Button, GridBox, Layout, ButtonStyle
header = Button(description='Header',
layout=Layout(width='auto', grid_area='header'),
style=ButtonStyle(button_color='lightblue'))
main = Button(description='Main',
layout=Layout(width='auto', grid_area='main'),
style=ButtonStyle(button_color='moccasin'))
sidebar = Button(description='Sidebar',
layout=Layout(width='auto', grid_area='sidebar'),
style=ButtonStyle(button_color='salmon'))
footer = Button(description='Footer',
layout=Layout(width='auto', grid_area='footer'),
style=ButtonStyle(button_color='olive'))
GridBox(children=[header, main, sidebar, footer],
layout=Layout(
width='50%',
grid_template_rows='auto auto auto',
grid_template_columns='25% 25% 25% 25%',
grid_template_areas='''
"header header header header"
"main main . sidebar "
"footer footer footer footer"
'''))
I don't get any output. Does anyone know why? Many thanks in advance :)

Modifying a clipboard content to be treated as HTML

When I “copy an image” on the web (by highlighting the image and ctrl+C) and then passed it into the text view of the HTML WYSIWYG editor (not the source code editor) the picture is displayed. Even though I paste in the text editor ( source code editor), the content of the clipboard is understood by the editor as an html code.
For example, if I simply paste “<img src="someURL" />in the text editor, it will be added in the source code as “<p><img src="someURL" /></p>” so this clipboard isn’t understood by the editor as an html code.
So how should I modify the content of my clipboard so that an HTML WYSIWYG editor understand it as an html code even though I am pasting it in the text view (not source code editor)?
What I want to do in more details:
when I have the URL of an image stored in my clipboard, I want to be able to add the image to the HTML WYSIWYG editor without having to switch to the source code editor. So I would like to transform the content of my clipboard (by adding some code before and after the URL) so it is understood as HTML code (just like the example mentioned above) by my HTML WYSIWYG editor.
Edit: to better target the answer here is what I try to achieve. When I use shareX to upload a picture, ShareX store automatically this (private) shareable URL in the clipboard. https://drive.google.com/open?id=XXXX
This code convert it in an embedded format. But I'm still looking for a way to store that as html format.
#URL_to_Picture.py
#
#(xxx=FileID)
#
#You need that kind of URL to be able to embed the picture in an editor: https://drive.google.com/uc?export=view&id=XXXX
#
#This script does a part of the job by converting Google drive URL into an embedded (and permanent) link:
from jaraco import clipboard
UrlShareX = clipboard.paste_text()
UrlShareX=UrlShareX.replace("https://drive.google.com/file/d/", "")
UrlShareX=UrlShareX.replace("/view?usp=drivesdk", "")
UrlShareX=UrlShareX.replace("/view?usp=sharing", "")
UrlShareX=UrlShareX.replace("https://drive.google.com/open?id=", "")
URL= '<img src="https://drive.google.com/uc?export=view&id={}" />'.format(UrlShareX)
clipboard.copy_html(URL)
To try on ShareX:
You must set the access to Google drive in ShareX menu:
destination/destination settings/google drive.
You must set the ShareX menu: “after upload task” to “copy URL to
clipboard”
I want to be able to add the image to the HTML WYSIWYG editor without having to switch to the source code editor
AHK solution: use a hotkey like ctrl+shift+v
you have plain text in clipboard: https://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg?v=47faa659a05e
go in WYSIWYG editor and press ctrl+shift+v, it will be pasted in HTML format
HTML format is a clipboard format, so an image will be shown.
what you need is here: WinClipv2\imgSrc to HTML Format\src in clip.ah2
I put the code in a repo because there's a library to include:
https://github.com/FuPeiJiang/WinClipv2
READ the README.md
You can do this:
Install HtmlClipboard : copy the script, save it as HtmlClipboard.py in C:\Python##\Lib\site-packages\
Save the script below as image_link_as_html.py(I used some of your code in your question):
Create a shorcut for the script in step to (right click on the file image_link_as_html.py, and select create a shorcut)
Right click on the shorcut, select Properties, and and add a keyboard shorcut in Shorcut key.
That's it. When you have an image url in our clipboard, you can just press your keyboard shorcut and you can paste your image directly in the html mode of you editor.
image_link_as_html.py (Python34):
from tkinter import Tk
root = Tk()
root.withdraw()
image_url = root.clipboard_get()
# send <img src="https://image_url" alt="" /> to an "HTML format clipboard"
import HtmlClipboard
HtmlClipboard.PutHtml("<img src=\"http://"+image_url+" \" alt=\"\"/>")
To address the part about ShareX, you could use this scrip instead:
from tkinter import Tk
root = Tk()
root.withdraw()
UrlShareX = root.clipboard_get()
# remove everything except the file google ID: this part is not needed
UrlShareX=UrlShareX.replace("https://drive.google.com/file/d/", "")
UrlShareX=UrlShareX.replace("/view?usp=drivesdk", "")
UrlShareX=UrlShareX.replace("/view?usp=sharing", "")
UrlShareX=UrlShareX.replace("https://drive.google.com/open?id=", "")
UrlShareX=UrlShareX.replace("/view", "")
# send <img src="https://drive.google.com/uc?export=view&id=xxx " alt="" /> to an "HTML format clipboard"
import HtmlClipboard
HtmlClipboard.PutHtml("<img src=\"https://drive.google.com/uc?export=view&id="+UrlShareX+" \" alt=\"\"/>")

Folium map not displaying

Running on canopy version 1.5.5.3123
With;
Folium Version: 0.1.2, Build: 1
The following code;
import folium
import pandas as pd
LDN_COORDINATES = (51.5074, 0.1278)
from IPython.display import HTML
import shapefile
#create empty map zoomed in on London
LDN_COORDINATES = (51.5074, 0.1278)
map = folium.Map(location=LDN_COORDINATES, zoom_start=12)
display(map)
Returns
<folium.folium.Map at 0x10c01ae10>
But nothing else.
How do i get to display a map within an ipython notebook?
You can also save the map as html and then open it with webbrowser.
import folium
import webbrowser
class Map:
def __init__(self, center, zoom_start):
self.center = center
self.zoom_start = zoom_start
def showMap(self):
#Create the map
my_map = folium.Map(location = self.center, zoom_start = self.zoom_start)
#Display the map
my_map.save("map.html")
webbrowser.open("map.html")
#Define coordinates of where we want to center our map
coords = [51.5074, 0.1278]
map = Map(center = coords, zoom_start = 13)
map.showMap()
_build_map() doesn't exist anymore. The following code worked for me
import folium
from IPython.display import display
LDN_COORDINATES = (51.5074, 0.1278)
myMap = folium.Map(location=LDN_COORDINATES, zoom_start=12)
display(myMap)
Considering the above answers, another simple way is to use it with Jupiter Notebook.
for example (on the Jupiter notebook):
import folium
london_location = [51.507351, -0.127758]
m = folium.Map(location=london_location, zoom_start=15)
m
and see the result when calling the 'm'.
I've found this tutorial on Folium in iPython Notebooks quite helpful. The raw Folium instance that you've created isn't enough to get iPython to display the map- you need to do a bit more work to get some HTML that iPython can render.
To display in the iPython notebook, you need to generate the html with the myMap._build_map() method, and then wrap it in an iFrame with styling for iPython.
import folium
from IPython.display import HTML, display
LDN_COORDINATES = (51.5074, 0.1278)
myMap = folium.Map(location=LDN_COORDINATES, zoom_start=12)
myMap._build_map()
mapWidth, mapHeight = (400,500) # width and height of the displayed iFrame, in pixels
srcdoc = myMap.HTML.replace('"', '"')
embed = HTML('<iframe srcdoc="{}" '
'style="width: {}px; height: {}px; display:block; width: 50%; margin: 0 auto; '
'border: none"></iframe>'.format(srcdoc, width, height))
embed
Where by returning embed as the output of the iPython cell, iPython will automatically call display.display() on the returned iFrame. In this context, you should only need to call display() if you're rendering something else afterwards or using this in a loop or a function.
Also, note that using map as a variable name may might be confused with the .map() method of several classes.
Is there a reason you are using an outdated version of Folium?
This ipython notebook clarifies some of the differences between 1.2 and 2, and it explains how to put folium maps in iframes.
http://nbviewer.jupyter.org/github/bibmartin/folium/blob/issue288/examples/Popups.ipynb
And the code would look something like this (found in the notebook above, it adds a marker, but one could just take it out):
m = folium.Map([43,-100], zoom_start=4)
html="""
<h1> This is a big popup</h1><br>
With a few lines of code...
<p>
<code>
from numpy import *<br>
exp(-2*pi)
</code>
</p>
"""
iframe = folium.element.IFrame(html=html, width=500, height=300)
popup = folium.Popup(iframe, max_width=2650)
folium.Marker([30,-100], popup=popup).add_to(m)
m
The docs are up and running, too, http://folium.readthedocs.io/en/latest/
There is no need to use iframes in 2022. To display the map, simply use the
{{ map | safe }} tag in html and _repr_html_() method in you view. It is also not necessary to save the map to the template
sample.py
#app.route('/')
def index():
start_coords = (46.9540700, 142.7360300)
folium_map = folium.Map(location=start_coords, zoom_start=14)
return folium_map._repr_html_()
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ folium_map | safe }}
</body>
</html>
i have same error and nothing work for me
finally i found it
print(dir(folium.Map))
see method save dose not exist instead use

save plotly plot to local file and insert into html

I am using python and plotly to product interactive html report. This post gives a nice framework.
If I produce the plot(via plotly) online, and insert the url into the html file, it works but refreshing the charts takes a long time. I wonder if I could produce the chart offline and have it embedded in the html report, so that loading speed is not a problem.
I find plot offline would generate a html for the chart, but I don't know how to embed it in another html. Anyone could help?
There is a better alternative as of right now, that is to do offline plotting into a div, rather than a full html.
This solution does not involve any hacks.
If you call:
plotly.offline.plot(data, filename='file.html')
It creates a file named file.html and opens it up in your web browser. However, if you do:
plotly.offline.plot(data, include_plotlyjs=False, output_type='div')
the call will return a string with only the div required to create the data, for example:
<div id="82072c0d-ba8d-4e86-b000-0892be065ca8" style="height: 100%; width: 100%;" class="plotly-graph-div"></div>
<script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("82072c0d-ba8d-4e86-b000-0892be065ca8",
[{"y": ..bunch of data..., "x": ..lots of data.., {"showlegend": true, "title": "the title", "xaxis": {"zeroline": true, "showline": true},
"yaxis": {"zeroline": true, "showline": true, "range": [0, 22.63852380952382]}}, {"linkText": "Export to plot.ly", "showLink": true})</script>
Notice how its just a tiny portion of an html that you are supposed to embed in a bigger page. For that I use a standard template engine like Jinga2.
With this you can create one html page with several charts arranged the way you want, and even return it as a server response to an ajax call, pretty sweet.
Update:
Remember that you'll need to include the plotly js file for all these charts to work.
You could include
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
just before putting the div you got. If you put this js at the bottom of the page, the charts won't work.
Option 1: Use plotly's offline functionality in your Jupyter Notebook (I suppose you are using a Jupyter Notebook from the link you are providing). You can simply save the whole notebook as a HTML file. When I do this, the only external reference is to JQuery; plotly.js will be inlined in the HTML source.
Option 2: The best way is probably to code directly against plotly's JavaScript library. Documentation for this can be found here: https://plot.ly/javascript/
Update: Calling an internal function has never been a good idea. I recommend to use the approach given by #Fermin Silva. In newer versions, there now is also a dedicated function for this: plotly.io.to_html (see https://plotly.com/python-api-reference/generated/plotly.io.to_html.html)
Hacky Option 3 (original version for reference only): If you really want to continue using Python, you can use some hack to extract the HTML it generates. You need some recent version of plotly (I tested it with plotly.__version__ == '1.9.6'). Now, you can use an internal function to get the generated HTML:
from plotly.offline.offline import _plot_html
data_or_figure = [{"x": [1, 2, 3], "y": [3, 1, 6]}]
plot_html, plotdivid, width, height = _plot_html(
data_or_figure, False, "", True, '100%', 525)
print(plot_html)
You can simply paste the output somewhere in the body of your HTML document. Just make sure that you include a reference to plotly in the head:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
Alternatively, you can also reference the exact plotly version you used to generate the HTML or inline the JavaScript source (which removes any external dependencies; be aware of the legal aspects however).
You end up with some HTML code like this:
<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<!-- Output from the Python script above: -->
<div id="7979e646-13e6-4f44-8d32-d8effc3816df" style="height: 525; width: 100%;" class="plotly-graph-div"></div><script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("7979e646-13e6-4f44-8d32-d8effc3816df", [{"x": [1, 2, 3], "y": [3, 1, 6]}], {}, {"showLink": false, "linkText": ""})</script>
</body>
</html>
Note: The underscore at the beginning of the function's name suggests that _plot_html is not meant to be called from external code. So it is likely that this code will break with future versions of plotly.
In addition to the other answers, another possible solution is to use to_json() on the plotly figure.
No need for custom JSON serializer or use of internal solutions.
import plotly
# create a simple plot
bar = plotly.graph_objs.Bar(x=['giraffes', 'orangutans', 'monkeys'],
y=[20, 14, 23])
layout = plotly.graph_objs.Layout()
fig = plotly.graph_objs.Figure([bar], layout)
# convert it to JSON
fig_json = fig.to_json()
# a simple HTML template
template = """<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id='divPlotly'></div>
<script>
var plotly_data = {}
Plotly.react('divPlotly', plotly_data.data, plotly_data.layout);
</script>
</body>
</html>"""
# write the JSON to the HTML template
with open('new_plot.html', 'w') as f:
f.write(template.format(fig_json))
Thought the answer needs an update based on recent version. (plotly==4.9.0)
fig.write_html("path/to/file.html")
reference: plotly documentation
I wasn't able to get any of these solutions to work. My goal was to generate plots in one notebook and publish them in another, so persisting the plot HTML wasn't as important for me as simply having some method for serializing the plot to disk to be rebuilt somewhere else.
The solution I came up with is to serialize the fig object to JSON, and then use plotly's "json chart schema" to build the plot from JSON. This demo is all python, but it should be trivial to build a plot in HTML using this JSON-serialization strategy and invoking the plotly javascript library directly, if that's what you need.
import numpy as np
import json
from plotly.utils import PlotlyJSONEncoder
from plotly.offline import download_plotlyjs, init_notebook_mode, iplot
import plotly.graph_objs as go
init_notebook_mode()
def plotlyfig2json(fig, fpath=None):
"""
Serialize a plotly figure object to JSON so it can be persisted to disk.
Figures persisted as JSON can be rebuilt using the plotly JSON chart API:
http://help.plot.ly/json-chart-schema/
If `fpath` is provided, JSON is written to file.
Modified from https://github.com/nteract/nteract/issues/1229
"""
redata = json.loads(json.dumps(fig.data, cls=PlotlyJSONEncoder))
relayout = json.loads(json.dumps(fig.layout, cls=PlotlyJSONEncoder))
fig_json=json.dumps({'data': redata,'layout': relayout})
if fpath:
with open(fpath, 'wb') as f:
f.write(fig_json)
else:
return fig_json
def plotlyfromjson(fpath):
"""Render a plotly figure from a json file"""
with open(fpath, 'r') as f:
v = json.loads(f.read())
fig = go.Figure(data=v['data'], layout=v['layout'])
iplot(fig, show_link=False)
## Minimial demo ##
n = 1000
trace = go.Scatter(
x = np.random.randn(n),
y = np.random.randn(n),
mode = 'markers')
fig = go.Figure(data=[trace])
#iplot(fig)
plotlyfig2json(fig, 'myfile.json')
plotlyfromjson('myfile.json')
EDIT: Per discussion on the associated github issue, this is probably the current best approach.
Easiest way is to use pio from plotly
import plotly.io as pio
pio.write_html(fig, file='Name.html', auto_open=True)
I have used it a ton of lots to store my graphs before important meetings
You can also use an iframe according to an answer to the question how to embed html into ipython output?
plotly.offline.plot(fig, filename='figure.html',validate=False)
from IPython.display import IFrame
IFrame(src='./figure.html', width=1000, height=600)
To improvise the below code you could just call, to_plotly_json() for ex:,
def plotlyfig2json(fig, fpath=None):
"""
Serialize a plotly figure object to JSON so it can be persisted to disk.
Figures persisted as JSON can be rebuilt using the plotly JSON chart API:
http://help.plot.ly/json-chart-schema/
If `fpath` is provided, JSON is written to file.
Modified from https://github.com/nteract/nteract/issues/1229
"""
redata = json.loads(json.dumps(fig.data, cls=PlotlyJSONEncoder))
relayout = json.loads(json.dumps(fig.layout, cls=PlotlyJSONEncoder))
fig_json=json.dumps({'data': redata,'layout': relayout})
if fpath:
with open(fpath, 'wb') as f:
f.write(fig_json)
else:
return fig_json
--------------------------------------------
Simple way:
fig = go.Figure(data=['data'], layout=['layout'])
fig.to_plotly_json()
In Plotly 5 (and likely in 4 as well), BaseFigure.to_html has include_plotlyjs argument that is True by default.
Specifies how the plotly.js library is included/loaded in the output div string.
If True, a script tag containing the plotly.js source code (~3MB) is included in the output. HTML files generated with this option are fully self-contained and can be used offline.
Funnily enough Plotly figure HTML embedding can be illustrated with Pyodide right here.
const plotlyScript = `
import plotly.express as px
fig = px.bar(y=[0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
fig.to_html(full_html=False)
`
async function main() {
const pyodideUrl = 'https://cdn.jsdelivr.net/pyodide/v0.17.0/full/'
const pyodide = await loadPyodide({'indexURL': pyodideUrl})
await pyodide.loadPackage(['pandas']) // needed for plotly
const html = await pyodide.runPythonAsync(plotlyScript)
const fragment = document.createRange().createContextualFragment(html)
const output = document.getElementById('plotly-output')
output.textContent = ''
output.append(fragment)
}
main()
<script type="text/javascript" src="https://cdn.jsdelivr.net/pyodide/v0.17.0/full/pyodide.js"></script>
<div id="plotly-output">Loading pyodide... It may take a minute.</div>
to embed it in another page just use
<iframe width="560" height="315" title="Plot1" src="./scatter1.html"></iframe>
But why go with the trouble when you can not save it to a file and instead it, embed it directly
import plotly.offline as pyo
import plotly.graph_objs as go
import numpy as np
#generate the Plot
np.random.seed(42)
random_x = np.random.randint(1,101,100)
random_y = np.random.randint(1,101,100)
data = [go.Scatter(
x = random_x,
y = random_y,
mode = 'markers',
)]
the_plot= pyo.plot(data, include_plotlyjs=False, output_type='div')
print(the_plot)
num=11
strTable = '<html><head><title>Plots and Reports</title><script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head><body><table style="width:100%"><tr><th>Plot</th><th>Something else</th></tr>'
strRW = "<tr><td>"+the_plot+ "</td><td>"+str(num)+"</td></tr>"
strTable = strTable+strRW
strTable = strTable+"</table></body></html>"
hs = open("theReport.html", 'w')
hs.write(strTable)
I have recently needed to export Plotly Chart to HTML files.
Here is the simple proper way to do it in 2019.
import plotly.offline
plot(figure, "file.html")
If you want to insert fig (go.Figure) in HTML, maybe you should try use it.
Note: where the fig is one instance of go.Figure and fig contain your plot.
import json
import plotly.graph_objects as go
# step 1 convert fig to json
data = fig.to_json() #return one string
# step 2, save data in the file
filename = 'name_file.json'
with open ('' + filename + 'w') as file:
json.dump(data, file, indent=4)
After you will be able to insert the json file in HTML code, but you should insert dependencies.
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
Just adding to this thread for anyone who is looking to render a plotly figure into a HTML template as a HTML readable string. I recently had to do this and wanted to share...
Basically, if you have a HTML file where you want to place a plotly figure as a static image, one method is to insert an img class and add a string representation of the figure to the src kwarg. For example:
<img
class="max-width"
border="0"
style="display:block; padding:0px; line-height: 0px; font-size: 0px; border:0px; color:#000000;text-decoration:none;max-width:100% !important; width:100%;"
align="top"
height="350"
width="1000"
alt=""
src="" <---- this is where you can add a string rep of figure
>
To generate the string rep of any figure from plotly you can use the following function:
def render_base64_image_from_plotly_fig(fig):
"""Render a base64 encoded image from a plotly figure.
Args:
fig (dict): Plotly figure information (data and layout).
Returns:
str: base64 encoded string of plotly graph.
"""
# render figure to .png image
img_bytes = fig.to_image(format="png")
# encode into b64
encoding = b64encode(img_bytes).decode()
# create b64 image placeholder
img_b64 = "data:image/png;base64," + encoding
return img_b64
The output string can be inserting into the src="" and you will have a HTML rendered version of your plotly graph.
NOTE: watch out for truncation in the output string if you are copying straight from an IDE... this caught me out and will cause a headache. Basically a truncated base64 string will truncate with a '.' but '.' is a forbidden char in a base64 string. If you want to guaranteed that this doesn't happen, just write the output string to a .txt file on your machine and then copy and paste from it. i.e.
with open('html.txt', 'w') as f:
f.write(img_b64)
f.close()
I hope that this helps someone!
As alternative to Plotly, you can use utilmy which save HTML
on disk without extra config:
!pip install utilmy
from utilmy.viz import vizhtml as vi
import pandas as pd
url='https://raw.githubusercontent.com/AlexAdvent/high_charts/main/data/stock_data.csv'
df = pd.read_csv(url)
doc.h2('Stock Market Analysis')
doc.h4('plot Data in table format')
doc.table(df, table_id="test", custom_css_class='intro',use_datatable=True)
doc.hr()
doc.h4('Stock tseries graph')
doc.plot_tseries(
df,coldate = 'Date',
date_format = '%m/%d/%Y',
coly1 = ['Open', 'High', 'Low', 'Close'],
coly2 = ['Turnover (Lacs)'],title = "Stock",
)
doc.save('stock market analysis.html')

Categories