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.
Related
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)
I want to display a simple map with Folium in Jupyter notebooks.
The code below (and as shown in the picture) should work in Jupyter notebooks, but instead of displaying a map I just get an empty space.
# define the world map
world_map = folium.Map()
# display world map
world_map
I already tried restarting the kernel and using different browsers (safari, chrome). I also made sure that no content blocker is active. But no difference.
Does anyone know what I need to do to be able to see the map?
With a little help from my friends I managed to find the root cause. The problem were the firewall settings in the router. Some servers, where the folium maps got their data from, were blacklisted. That's why the maps were not displayed.
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
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.
I am using plot.ly to plot some graphs on some data. The graph is shown correctly but I would like to get a url to the graph that is hosted on plot.ly/username/xxx. Is there a way to get the url programmatically? I checked the plot.ly documentation but did not come across this option.
By default when creating plot. The URL are passed by the function
import plotly.plotly as py
url = py.plot(fig, filename='stacked-bar')