Revert plotly html graph back to plolty object to use in dash - python

I'm making a dashboard for a BI/DS project.
So far I've managed to make all ETL pipelines and even built some endpoints in flask_RESTful to present single graphs generated using plotly.
However, since I use Flask_RESTful, my code returns all graphs in div format.
Now I want to use them in dash without having to duplicate or change my code (I want to keep the raw html backends so the client can embed it in his own website if wanted).
This is what I return in my back-end:
return plotly.offline.plot(fig, filename='plot', include_plotlyjs=False, auto_open=False,
config={"displayModeBar": False, "showTips": False}, output_type='div')
How do I insert that into my dash layout?
If I do
dash_app.layout = html.Div(children=[
html.H1(children=my_plot_function())
])
All I get is raw html (string)
Is there some way to revert the "plot as div" function in plotly to use them in dash?
(Using Dash is much simpler for me than trying to learn React or anything like that)

Related

Translating Plotly Dash to other language

I have made a dashboard in Plotly Dash. Everything looks perfect, however the main problem I am facing is that of localization(translating the elements in Dashboard to other language). Without translating, the dashboard will be worthless. I have tried following method for translating the elements:
#app.callback(
Output('1', 'children' ),
Output('2', 'children' ),
Input("lang-dropdown", "value"))
def update_card(value):
if value=='Ar':
return 'مقارنة المبيعات', 'ضبط المبيعات'
else:
return 'Sales Comparison', 'Sales Tuning'
However, there are lot of elements and I want it to translate it more efficiently like that used in other language(like in json format). I have looked into other methods like Flask Babel translating as well, but I am a beginner and it is difficult for me to do it at this stage. Can someone please guide me how can I localize my dashboard? Will be grateful.

How to Embed a Plotly Interactive Graph in Webpage

I have an interactive graph generated by Plotly in Python that I saved to an html file using plotly.offline.plot(fig, filename='/tmp/interactiveGraph.html')
I am now trying to embed this interactive graph into some kind of webpage, using either Dash or Django. I'm leaning toward Django at the moment, given that I have an html version of the graph. Which would be better?
My code for the webpage is in a separate file from the code where I am creating the graph.
A lot of the tutorials I've found online just say to add a few lines to the template, but I don't know how to get those lines that they've described.
tl;dr: I'm looking for guidance as how to integrate an html file-for a Plotly interactive graph-with a web python script using Django or Dash
Side Question:
what is the difference between
plotly.offline.plot(fig, include_plotlyjs=False, output_type='div')
and what I have above?
Reference:
https://github.com/ricleal/DjangoPlotLy
https://www.pythonsetup.com/how-implement-data-visualization-django-and-plotly/
I would highly reccomend Django, its a great framework. As for this, the best option is to generate the data via JavaScript and Plotly has a great library for this. If you must use python, then Django can be used. Assuming you are familiar with Django, inside of your view you can collect your data and build your graph ( I would reccomend a celery task for something long running like this unless they are small graphs), and you can then collect the return from creating the graph in div format. This will return a string that holds all the needed html and css for the graphs. Put this inside of you get_context_data() method in your view and place it into the dictionary. You can the use that object inside of a template. I have done this before, if you are having a hard time feel free to DM me. Hope this helps some!
In regards to your side question, I believe having False for including JS will make the graph a bit smaller assuming you have an include for the plotly JS library. They might have done this in a newer release to make the graphs faster as they were significantly slower in the browser from python that the JS rendered one.

Triggering audio hover effects in plotly

I recently discovered plotly and I think it's a great tool to share interactive plots over the internet. Since my research is in audio signal processing, I'd like to use it to convert my matlab/python plots into interactive plots allowing the user to play the different audio signals used to generate the plot.
For instance, if a bar plot shows a bunch of bars corresponding to as many different speech enhancement strategies, I'd like to find a way to play the different audio signals when hovering on the different lines.
I found this example (or here, to open it with codePen) to add custom hover effects to a plotly plot; specifically, the example deals with showing an image when hovering over a bar of the plot. I'd like to have something similar, but triggering an audio playback instead of an image visualization.
How could the code be edited to do this? (e.g. to play a given sound when hovering over one of the bars)
I see following approaches which can work for such visualization:
There is an ability to build own components with dash. Here is a tutorial: react-for-python-developers and cookiecutter generator. As an example here you can find a component with wrapped react-sound: dash_audio_components.
It can be installed and used in "dash"-generated web interface for plotly by the following way:
import dash
import dash_audio_components
import dash_core_components
app = dash.Dash('app-name')
...Set serving locally because this component isn't placed to cdn
app.scripts.config.serve_locally = True
app.layout = html.Div(
children=[
dcc.Graph(
id='chart-id',
figure=<FigureObj>
),
dash_audio_components.DashAudioComponents(
id='audio-player',
url=None,
playStatus='STOPPED'
)
]
)
#app.callback(dash.dependencies.Output('audio-player', 'playStatus'),
[dash.dependencies.Input('chart-id', 'clickData')])
def set_status(click_data):
...Preserve somewhere status of audio-player and return changed state
...hover or unhover events can be handled as well
#app.callback(dash.dependencies.Output('audio-player', 'url'),
[dash.dependencies.Input('chart-id', 'clickData')])
def set_status(click_data):
...Return url from textual information received from click_data
This article describes good practices of sharing some state: Sharing data between callbacks
Another way which can be more applicable for those who
experienced with web development is implementing a separate SPA with react-plotly and passing data to it from service endpoints, here is how you can bind sounds to existing "plotly" click event binding to click events, it can be done on componentDidMount method call or in JSX as callback with "plotly_click" or "plotly_hover" property. There are plenties of React components to play audios. Application blueprint can be generated by 'yeoman' as well for simplicity sake. Codepen example with plotly.js library to handle 'clicks' and 'unhover' events and play sound: codepen plotly

How to change the language / locale in Dash (Plotly) or the label of the Plotly toolbar?

Plotly Toolbar
I have been able to successfully modify Plotly's toolbar in Dash using a dict (config) passed to dash_core_components.Graph
Now I want to change the "tooltip" or label of the remaining buttons to another language.
The documentation states that I can change de locale (language) of the labels using the "locale" parameter. I've seen this both in JavaScript and R docs, being applied to Plotly Graphs or to dash_core_components.Graph:
https://plot.ly/r/locales/
Now I need to do this in Python, but I haven't been able to do this. This is what I've tried:
config_plots = {'modeBarButtonsToRemove':["sendDataToCloud","lasso2d","pan2d","autoScale2d","select2d","zoom2d","zoomIn2d", "zoomOut2d"],
"locale":"de"}
dcc.Graph(id="plot",config=config_plots,
figure={"data":plotdata,"layout":layout})
I have added the locale parameter as well to plotly graphs (plotly.graph_objs) and tried with different locales I know that exist, but I've had no luck so far.
The question:
How can I customize the text of the labels? Am I missing something using the locale parameter? Is there any way to change the text of the labels so I can translate it without using the locale parameter?
Please note that I know very little of JavaScript so I would prefer to do this in Python if possible
According to this plotly documentation you need to register any new language first.
In your case this means you need to add
https://cdn.plot.ly/plotly-locale-de-latest.js
to your dashboard.
Either by
app.scripts.append_script({"external_url": "https://cdn.plot.ly/plotly-locale-de-latest.js"})
or by downloading the js file and coping it to the assets folder in your dashboards root folder.
See https://dash.plot.ly/external-resources for more information.
In django-dash-plotly I had to do this:
Add the localization script to the external scripts:
app = DjangoDash(
self.name,
external_scripts=[
"/static/plotly/plotly-locale-es.js",
],
)
Configure the Graph with the locale.
app.layout = [
dcc.Graph(
id="my_graph",
config={"locale": 'es'},
)
]

Build interactive map from python

I am trying to build webpage showing an interactive map (taking up 100% of the page) where I present points or lines with information. Plotly seems perfect for this and I really like its visualization but it does however not have support for maps such as Open Street Map built in, it uses Mapbox for this. I don't have anything against Mapbox, but from what I can find it is free of charge up to a certain numbers of views (while it uses OSM).
Simply said: is there an easy (as open source and free to use) way using python to build such a webpage with a map that shows information?
There is indeed! You can use Mapbox GL JS without plotly. There are example of html code in here that will create these full sized maps for you. They can be satellite or just a plain map.
Drawing lines:
https://docs.mapbox.com/mapbox-gl-js/example/geojson-line/
Creating a popup onclick:
https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/
You can indeed use OSM maps free of charge without restrictions or a Mapbox API account in Plotly and Dash, see https://plotly.com/python/mapbox-layers/:
Base Maps in layout.mapbox.style
The accepted values for layout.mapbox.style are one of:
"white-bg" yields an empty white canvas which results in no external HTTP requests
"open-street-map", "carto-positron", "carto-darkmatter", "stamen-terrain", "stamen-toner" or "stamen-watercolor" yeild maps composed of raster tiles from various public tile servers which do not require signups or access tokens
"basic", "streets", "outdoors", "light", "dark", "satellite", or "satellite- streets" yeild maps composed of vector tiles from the Mapbox service, and do require a Mapbox Access Token or an on-premise Mapbox installation.
A Mapbox service style URL, which requires a Mapbox Access Token or an on-premise Mapbox installation.
A Mapbox Style object as defined at https://docs.mapbox.com/mapbox-gl-js/style-spec/
Here is a code example from the same plotly documentation that uses the OSM basemap without any authetification token:
import pandas as pd
us_cities = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv")
import plotly.express as px
fig = px.scatter_mapbox(us_cities, lat="lat", lon="lon", hover_name="City", hover_data=["State", "Population"],
color_discrete_sequence=["fuchsia"], zoom=3, height=300)
fig.update_layout(mapbox_style="open-street-map")
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
As for builing an actual website, I recommend using Dash, which is a webserver well integrated with plotly.

Categories

Resources