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
Related
I just deployed a dashboard on Google Cloud and shared it with a friend to check if he could access it. I asked for a screen print to check if everything was ok.
To my surprise, the dashboard that appeared to him is very different from what appears to me. On his screen, the text fonts are all misconfigured and the size of the graphics are different, in addition to not being centered on the screen.
I didn't think this problem would happen, since the dash is online on the internet.
Can anyone tell me how I can standardize the view for any user?
I don't know if it helps but all the layout code (html+css+python) is in the same app.py file.
Obs
There is no Go.figures or Bootstrap in my code. It's just simples plotly charts made with plotly.express.
Here is an example cytoscape graph that I created using this site as reference here
I was wondering if its possible to show the tooltips when hovering on each node in a graph in the same way that plotly can do to its graphs (like this)
Dash Cytoscape does not have a built-in tooltip. It's possible to use hover callbacks (documented in the event callback guide) to update the content of a separate component (such as a html.P on the side). However that will not behave the same way as a tooltip.
You might also be able to build a custom component (using the component boilerplate) that follows your cursor and display custom information (given by the hoverData prop) whenever it is updated by a hover callback. However, that would require knowledge of JavaScript and React, which can be learned from the React for Python developers primer.
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.
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.
I'd like to output the image to the web created in matplotlib having the very same functionality like it has on desktop when you run the image.show(), for example scaling, moving along the plot more thoroughly.
I've checked out #stack and got old post only offering static images or gif or matplotlib.animate()
I aslo had a look at matplotlib widgets, but those are for desktop GUI only as far as I can see.
Please share some experience or ideas regarding how can I achieve it.
Thanks
Matplotlib is a server side library so you cannot do anything on the client side like that.
The closest you can come is to either use mpld3 (mpld3 works by converting a matplotlib graph into the html/js that a d3 js graph would need to render) or a different client side library that plots points.
The easiest way of serving pure matplotlib to the web is using a jupyter notebook.
Other than that, you may want to look at specific libraries like Plotly or bokeh.