internal links to jupyter notebook section in plotly figure - python

I am using Jupyter and Plotly to produce a set of plots, text and indicators that I then export in HTML, to produce a sort of "dashboard" that people can navigate to get data.
To produce an interactive table of contents, where users can click and go directly to the desired section, so far I followed this nice tutorial
https://sebastianraschka.com/Articles/2014_ipython_internal_links.html
The problem is that this only works with Markdown, and I would like to have instead something more adaptable and graphically pleasant.
I thought I could get away with producing a plotly multiplot with big clickable buttons to the different sections. Something like
--------------- --------------- ---------------
¦ Section 1 ¦ ¦ Section 2 ¦ ¦ Section 3 ¦
--------------- --------------- ---------------
So far, I'm able to get what I want using Markdowns. Internal link destinations in the notebook are defined as
from IPython.display import Markdown as md
#destination of an internal link
md(f"""<a id='Section_1'></a>""")
And they can be called as
md(f"""<a href='#Section_1'> Go to Section 1 </a>""")
Crucially, this also works when I export the notebook in html, which is the file I eventually send around.
However, when I try to put a link in a Plotly figure (via text annotation, for example) the situation is different. If I do something like that:
import plotly.graph_objects as go
import numpy as np
x = np.arange(10)
fig = go.Figure(data=go.Scatter(x=x, y=x**2))
fig.add_annotation(x=6, y=10,
text="<a href='#Section_1'>Go to Section 1</a>",
showarrow=False,
yshift=10)
fig.show()
two things can happen:
In the Jupyter notebook, if I click on the link, instead of jumping to the right session, it opens a new tab with a copy of the notebook, and then jumps to the session.
When I export it in html, the link is simply not transfered and - although clickable - nothing happens. Weirdly, if instead of referring to an internal section of the document I try an external link, say "www.wikipedia.com", it works just fine.
The code I use to export the notebook in html is
import plotly.offline as pyo
import plotly.io as pio
pyo.init_notebook_mode(connected=False)
pio.renderers.default = "notebook"
from nbconvert import HTMLExporter
from nbconvert import PDFExporter
from nbconvert.writers import FilesWriter
nb_name = 'My notebook'
exporter = HTMLExporter(exclude_input=True, exclude_output_prompt = True)
(body, resources) = exporter.from_filename(f'{nb_name}.ipynb')
write_file = FilesWriter()
write_file.write(
output=body,
resources=resources,
notebook_name=nb_name
)
Maybe the problem is how the link is exported in the html conversion, maybe it's with Plotly itself. Any idea or alternative I could use to get the result I want?

Related

saving a sankey to a file from jupyter

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()

Can't Render Google Directions Layer from HTML exported using Python embed_minimal_html

After exporting a jupyter-gmaps base map and directions to HTML using "ipywidgets.embed.embed_minimal_html" I'm having trouble showing the directions layers when I re-open the HTML map.
The base map and directions layers show up just fine in jupyter notebook as shown here:
Map and directions rendered in Jupyter Notebook
However, when the HTML file is re-opened using either a server (opened using "python -m http.server 8080"), or by double clicking on the saved file, or by using the code snippet below, only the base layer renders as shown here, along with some strange artifacts: What is rendered when the exported HTML is opened
import IPython
IPython.display.HTML(filename='testest.html')
The directions layers seem to be saving in the HTML because I get an error regarding the directions layers when I try to save the image, but the scripts aren't being rendered in the browser (Error about directions layer when opening the HTML file). Also, the following errors are displayed Chrome console.
Here is the code I used to generate this map, if someone could help me figure out how to get the directions layers to render in the exported map I would really appreciate it :) .
import gmaps
from ipywidgets.embed import embed_minimal_html,embed_data
import IPython
import os
#configure api
api_key = 'YOUR-API-KEY-HERE'
gmaps.configure(api_key=api_key)
#Define location 1, 2, and 3
Durango = (37.2753,-107.880067)
meow = (37.3654,-106.880067)
SF = (37.7749,-122.419416)
#Create the map
fig = gmaps.figure()
#create the layers
layer1 = gmaps.directions_layer(Durango, meow,travel_mode="DRIVING")
fig.add_layer(layer1)
layer2 = gmaps.directions_layer(Durango, SF,travel_mode="DRIVING")
fig.add_layer(layer2)
#Export the map and layers to HTML
embed_minimal_html(os.getcwd() + '\{}.html'.format("testest"), views=[fig],title='test')
#show the map in Jupyter
fig
Thanks!!

Line Graphs in Anaconda

I am writing a Python program to generate line graphs of cryptocurrency prices.
The goal is to be able to overlay multiple arbitrary pairs, i.e., BTC/USD + ETH/BTC, or BTC/USD + BCH/LTC + XRP/BTG, across the same horizontal timeline, similar to https://coinmarketcap.com/currencies/ethereum/
The bells and whistles in the above example are not required. It doesn't need click-to-zoom technology, the log-scale button, or fancy tool tips, if these features increase the implementation difficulty. Separate colors for each line would be helpful. This is the format of the data I have to work with:
https://min-api.cryptocompare.com/data/histominute?fsym=BTC&tsym=USD&limit=60&aggregate=1&e=Coinbase
https://min-api.cryptocompare.com/data/histominute?fsym=ETH&tsym=BCH&limit=30&aggregate=1&e=CCCAGG
Currently, I have Anaconda 3.6 on Visual Studio, which according to https://docs.anaconda.com/anaconda/packages/py3.6_win-64.html should include multiple packages to plot this data without needing to manually install third party code through a command line. However, when I try to import any of them (i.e., matplotlib, bokeh, seaborn), I receive a "ModuleNotFoundError" message, so I'm not sure if my Anaconda is functioning properly. What is the easiest way to graph this data with Anaconda?
The python interpreter in VSCode is probably not using your Anaconda installation. In the VSCode python shell, type import sys and then sys.version and it should tell you the version of python you are using.
Here is some code to get you started with doing this in bokeh, a library that comes with Anaconda. Instead of using Visual Studio (or Visual Studio Code--I'm not sure which one you are referring to), I used jupyter notebook, and some of the import here are specific to that environment (to show the bokeh graph inline). You may want to format the date differently.
from bokeh.plotting import figure, output_file, show
from bokeh.io import output_notebook
import numpy as np
output_notebook()
import requests
import datetime
from math import pi
def format_date(utc_time):
time = datetime.datetime.fromtimestamp(int(utc_time))
return time
url1 = "https://min-api.cryptocompare.com/data/histominute?fsym=BTC&tsym=USD&limit=60&aggregate=1&e=Coinbase"
url2 = "https://min-api.cryptocompare.com/data/histominute?fsym=ETH&tsym=BCH&limit=30&aggregate=1&e=CCCAGG"
r1 = requests.get(url1)
r2 = requests.get(url2)
r1_source = r1.json()["Data"]
r2_source = r2.json()["Data"]
r1_data = [i["close"] for i in r1_source]
r1_time = [format_date(i["time"]) for i in r1_source]
# r2_data = [i["close"] for i in r2_source]
# r2_time = [i["time"] for i in r2_source]
p = figure(plot_width=800, plot_height=400)
p.line(r1_time,r1_data, line_width=2)
# p.line(r2_time, r2_data, line_width=2, line_color="red")
p.xaxis.major_label_orientation = pi/4

Cast Plotly object to HTML and edit modeBar before plotting in IPython Notebook

I'm trying to edit the modeBarButtons of a plotly graph such that the 'save and edit plot in cloud' function becomes disabled. At first this didn't seem possible in Python. But this post pointed out a workaround for Python, by casting the object to HTML and editing the HTML code.
Unfortunately, the 'save and edit plot in cloud' functionality remains when I try the example code below:
import numpy as np
from IPython.display import display, HTML
from plotly.offline import download_plotlyjs, init_notebook_mode, plot
import plotly
import plotly.graph_objs as go
plotly.offline.init_notebook_mode()
# create sin data to plot
x = np.arange(0.0, 100.0, 0.1)
y = np.sin(x)
# create plot data, edit and plot
trace0 = go.Scatter(x=x,y=y, name="Sin")
HTML_code = plot([trace0], show_link=False, auto_open=False, output_type='div')
HTML_code = HTML_code.replace('modeBarButtonsToRemove:[]',
'modeBarButtonsToRemove:["sendDataToCloud"]')
display(HTML(HTML_code))
[Edit] Write to file:
The button is successfully removed when the edited HTML is written to file and opened in a browser.
Reloading the edited file into my notebook was unsuccessful:
from IPython.display import display, HTML
with open('./temp-plot.html', 'r') as file :
tempHTML = file.read()
display(HTML(tempHTML))
Javascript error adding output!
ReferenceError: Plotly is not defined
See your browser Javascript console for more details.
Using output_type='div' instead of output_type='file' (my preferred approach due to write restrictions for the final product):
The notebook seems to 'reload' plotlys' standard configuration and only insert the data from the HTML, leaving the edited JavaScript unused.
Any suggestions?
Regards,
Koen

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