Easily convert matplotlib plots from Python into interactive Leaflet web maps.

Overview

mplleaflet

mplleaflet is a Python library that converts a matplotlib plot into a webpage containing a pannable, zoomable Leaflet map. It can also embed the Leaflet map in an IPython notebook. The goal of mplleaflet is to enable use of Python and matplotlib for visualizing geographic data on slippy maps without having to write any Javascript or HTML. You also don't need to worry about choosing the base map content i.e., coastlines, roads, etc.

Only one line of code is needed to convert a plot into a web map. mplleaflet.show()

The library is heavily inspired by mpld3 and uses mplexporter to do most of the heavy lifting to walk through Figure objects.

Examples

Basic usage

The simplest use is to just create your plot using matplotlib commands and call mplleaflet.show().

>>> import matplotlib.pyplot as plt
... # Load longitude, latitude data
>>> plt.hold(True)
# Plot the data as a blue line with red squares on top
# Just plot longitude vs. latitude
>>> plt.plot(longitude, latitude, 'b') # Draw blue line
>>> plt.plot(longitude, latitude, 'rs') # Draw red squares

matplotlib x,y plot

Normally, displaying data as longitude, latitude will cause a cartographer to cry. That's totally fine with mplleaflet, Leaflet will project your data properly.

# Convert to interactive Leaflet map
>>> import mplleaflet
>>> mplleaflet.show()

Click to view final web page

Leaflet map preview

Disclaimer: Displaying data in spherical mercator might also cause a cartographer to cry.

show() allows you to specify different tile layer URLs, CRS/EPSG codes, output files, etc.

IPython Notebook embedding

Just use mplleaflet.display() to embed the interactive Leaflet map in an IPython notebook. Click here to see a live example.

Other examples

Why mplleaflet?

Other Python libraries, basemap and folium, exist to create maps in Python. However mplleaflet allows you to leverage all matplotlib capability without having to set up the background basemap. You can use plot() to style points and lines, and you can also use more complex functions like contour(), quiver(), etc. Furthermore, with mplleaflet you no longer have to worry about setting up the basemap. Displaying continents or roads is determined automatically by the zoom level required to view the physical size of the data. You should use a different library if you need fine control over the basemap, or need a geographic projection other than spherical mercator.

Installation

Install mplleaflet from PyPI using $ pip install mplleaflet.

Development

If developing for mplleaflet, mplexporter is a git submodule with its Python package files placed under the mplleaflet package. The Makefile copies the files into the appropriate location.

$ git submodule init
$ git submodule update
$ make
$ pip install -e .

Dependencies

Optional

  • pyproj Only needed if you only use non-WGS-84 projections.
  • GeoPandas To make your life easier.
Comments
  • Adding authors file.

    Adding authors file.

    @BibMartin @mariusvniekerk @michelleful @ocefpaf @mnfienen I'd like to put this on master soon. Please let me know if there are any objections or corrections that need to be made.

    opened by jwass 8
  • hack to avoid cross-origin pb in notebooks

    hack to avoid cross-origin pb in notebooks

    Issue

    I often work with a distant IPython notebook / jupyter server ; in that case, there are cross-origin issues in the browser, as leaflet.css and leaflet.js cannot be loaded.

    Fix

    I fix it in using urllib2 and asking python to download and serve these files. There may be cleaner ways to do that ; especially in adapting the template.

    Bonus

    And I take the occasion to put the rendered figure in an iframe, so that it's javascript does not interact with the notebook's. This also enables to create an iframe with the same size as the original matplotlib figure.

    opened by BibMartin 8
  • Is it possible to set the opacity of a plot?

    Is it possible to set the opacity of a plot?

    mplleaflet seems to respect most of the options you can set on a matplotlib plot, except for one crucial one, which is opacity. That is, at least AFAIK.

    Am I wrong (in that case, what's the parameter name!)? If not, then I believe that such a control should be made a feature.

    opened by ResidentMario 6
  • display() doesn't work - 'base64' is not a text encoding

    display() doesn't work - 'base64' is not a text encoding

    Hi. I've recently downloaded the package and have been messing around with some basic examples.

    The following snippet runs without error,

    %matplotlib inline
    
    import mplleaflet
    import matplotlib.pyplot as plt
    
    plt.plot([0,45], [0,45])
    
    mplleaflet.show()
    

    but changing mplleaflet.show() to mplleaflet.display() returns the following error

    ---------------------------------------------------------------------------
    LookupError                               Traceback (most recent call last)
    <ipython-input-6-a8022d0ab3fb> in <module>()
          6 plt.plot([0,45], [0,45])
          7 
    ----> 8 mplleaflet.display()
    
    C:\Program Files\Miniconda3\lib\site-packages\mplleaflet\_display.py in display(fig, closefig, **kwargs)
        153     # We embed everything in an iframe.
        154     iframe_html = '<iframe src="data:text/html;base64,{html}" width="{width}" height="{height}"></iframe>'\
    --> 155     .format(html = html.encode('base64'),
        156             width = '100%',
        157             height= int(60.*fig.get_figheight()),
    
    LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbitrary codecs
    

    I'm running Python 3.4.3, iPython 4.0.0 through Jupyter 4.0.6, matplotlib 1.4.3 and mplleaflet 0.0.4. OS is Win8.1 (64bit).

    Cheers, Eilam

    opened by ghost 6
  • Created HTML does not show map-tiles with Chrome or Edge

    Created HTML does not show map-tiles with Chrome or Edge

    I have created a map of a GPS-track. If i open the HTML-File with Chrome (99.0.4844.51) or Edge ( 99.0.1150.39) i only see my track on a blank area without the tile-data. With Firefox the map is displayed.

    opened by jibaer-izw 5
  • Add new parameter to fig_to_html function to manage the geojson float precision

    Add new parameter to fig_to_html function to manage the geojson float precision

    Motivation: the fig_to_html function embeds a geojson that can be very heavy when there are a lot of coordinates and features. According to this most of the time extra float precision on the coordinates doesn't have a visible effect.

    With the PR you can add float_precision to the fig_to_html function and when the geojson is created the floats will be formatted.

    Example:

    import mplleaflet
    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots()
    ax.plot((1,2.365485622,36.254685), (1,2,3.3))
    

    If we save the fig to html in the usual way we get:

    mplleaflet.fig_to_html(fig)
    

    We get

    ...
    var gjData = {
        "type": "FeatureCollection", 
        "features": [{
            "type": "Feature", 
            "geometry": {
                "type": "LineString", 
                "coordinates": [[1.0, 1.0], [2.365485622, 2.0], [36.254685, 3.3]]
            }, 
            "properties": {"color": "#1F77B4", "weight": 1.5, "opacity": 1, "fillOpacity": 1}
        }]
    };
    ...
    

    If we use the new keyword:

    mplleaflet.fig_to_html(fig, float_precision=3)
    

    We would get:

    ...
    var gjData = {
        "type": "FeatureCollection", 
        "features": [{
            "type": "Feature", 
            "geometry": {
                "type": "LineString", 
                "coordinates": [[1.000, 1.000], [2.365, 2.000], [36.255, 3.300]]
            }, 
            "properties": {"color": "#1F77B4", "weight": 1.500, "opacity": 1, "fillOpacity": 1}
        }]
    };
    ...
    

    The example above is not very representative but if you are using contours, for instance, the difference is very important.

    opened by kikocorreoso 5
  • Added several tiles options to maptiles.py

    Added several tiles options to maptiles.py

    I added several tiling options to maptiles.py. These include: Thunderforest Landscape, Esri Aerial, Esri National Geographic, and Stamen Watercolor.

    I hope you will consider pulling them in.

    Thanks! mike

    opened by mnfienen 5
  • plt.scatterplot c argument doesn't work

    plt.scatterplot c argument doesn't work

    When I run this example, I get the following traceback:

    import mplleaflet
    import matplotlib.pyplot as plt
    
    plt.scatter([0, 10, 0, 10], [0, 0, 10, 10], c=[1, 2, 3, 4])
    mplleaflet.display()
    
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-100-b851626ef3d4> in <module>()
          1 plt.scatter([0, 10, 0, 10], [0, 0, 10, 10], c=[1, 2, 3, 4])
    ----> 2 mplleaflet.display()
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplleaflet/_display.pyc in display(fig, closefig, **kwargs)
        136         plt.close(fig)
        137 
    --> 138     html = fig_to_html(fig, template="ipynb.html", **kwargs)
        139     return HTML(html)
        140 
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplleaflet/_display.pyc in fig_to_html(fig, template, tiles, crs, epsg)
         70     renderer = LeafletRenderer(crs=crs, epsg=epsg)
         71     exporter = Exporter(renderer)
    ---> 72     exporter.run(fig)
         73 
         74     attribution = _attribution + ' | ' + tiles[1]
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplexporter/exporter.pyc in run(self, fig)
         49             import matplotlib.pyplot as plt
         50             plt.close(fig)
    ---> 51         self.crawl_fig(fig)
         52 
         53     @staticmethod
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplexporter/exporter.pyc in crawl_fig(self, fig)
        116                                        props=utils.get_figure_properties(fig)):
        117             for ax in fig.axes:
    --> 118                 self.crawl_ax(ax)
        119 
        120     def crawl_ax(self, ax):
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplexporter/exporter.pyc in crawl_ax(self, ax)
        138                 self.draw_patch(ax, patch)
        139             for collection in ax.collections:
    --> 140                 self.draw_collection(ax, collection)
        141             for image in ax.images:
        142                 self.draw_image(ax, image)
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplexporter/exporter.pyc in draw_collection(self, ax, collection, force_pathtrans, force_offsettrans)
        270                                            offset_order=offset_order,
        271                                            styles=styles,
    --> 272                                            mplobj=collection)
        273 
        274     def draw_image(self, ax, image):
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplexporter/renderers/base.pyc in draw_path_collection(self, paths, path_coordinates, path_transforms, offsets, offset_coordinates, offset_order, styles, mplobj)
        253 
        254         for tup in self._iter_path_collection(paths, path_transforms,
    --> 255                                               offsets, styles):
        256             (path, path_transform, offset, ec, lw, fc) = tup
        257             vertices, pathcodes = path
    
    /Users/shoyer/miniconda/envs/rapid/lib/python2.7/site-packages/mplexporter/renderers/base.pyc in _iter_path_collection(paths, path_transforms, offsets, styles)
        190         N = max(len(paths), len(offsets))
        191 
    --> 192         if not path_transforms:
        193             path_transforms = [np.eye(3)]
        194 
    
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    

    Thanks for your work on this project! I can't believe I just discovered it yesterday :).

    opened by shoyer 5
  • contourf example doesn't work on my machine

    contourf example doesn't work on my machine

    I can't seem to get any contourf plots to work with mplleaflet. Other plot types (e.g., scatter plots) work fine.

    The example runs without any errors on my machine, but it generates a map with only the background layer.

    Any ideas for how to debug this?

    opened by shoyer 4
  • Read alpha as the `fillOpacity` property

    Read alpha as the `fillOpacity` property

    I am not sure if this is the best way to implement it because matplotlib's alpha is defined only once, while in leaflet we have opacity for the stroke opacity and fillOpacity for the patch opacity.

    However, I believe we need to override leaflet's default fillOpacity, which is only 0.2, to fix visualizations like this one:

    http://nbviewer.ipython.org/github/rsignell-usgs/mwra-wq/blob/master/notebooks/wq_test.ipynb

    opened by ocefpaf 3
  • added esri_worldtopo tiles

    added esri_worldtopo tiles

    The esri world topo maps are pretty good. They currently have better water feature coverage and building outlines in my area of interest than OSM (I should update OSM, but that is a different issue....)

    opened by smnorris 3
  • AttributeError: 'PatchCollection' object has no attribute 'get_offset_position'

    AttributeError: 'PatchCollection' object has no attribute 'get_offset_position'

    Hi,

    I am currently reproducing code for plotting maps of Germany (https://juanitorduz.github.io/germany_plots/).

    I try to get the interactive map running:

    import mplleaflet
    
    fig, ax = plt.subplots()
    
    berlin_df.plot(
        ax=ax,
        alpha=0.2
    )
    
    berlin_neighbourhoods_df.plot(
        ax=ax,
        column='neighbourhood_group',
        categorical=True,
        cmap='tab20',
    )
    
    mplleaflet.display(fig=fig)
    

    (one of the last steps of the tutorial)

    I already fixed the _gridOnMajor bug like suggested here: https://github.com/jwass/mplleaflet/issues/80 (thanks to @22tommibaer01).

    Unfortunately, I ran into another bug with the following error log:

    [...]
    File ~/.pyenv/versions/3.10.1/lib/python3.10/site-packages/mplleaflet/mplexporter/exporter.py:263, in Exporter.draw_collection(self, ax, collection, force_pathtrans, force_offsettrans)
        255 styles = {'linewidth': collection.get_linewidths(),
        256           'facecolor': collection.get_facecolors(),
        257           'edgecolor': collection.get_edgecolors(),
        258           'alpha': collection._alpha,
        259           'zorder': collection.get_zorder()}
        261 offset_dict = {"data": "before",
        262                "screen": "after"}
    --> 263 offset_order = offset_dict[collection.get_offset_position()]
        265 self.renderer.draw_path_collection(paths=processed_paths,
        266                                    path_coordinates=path_coords,
        267                                    path_transforms=path_transforms,
       (...)
        271                                    styles=styles,
        272                                    mplobj=collection)
    
    AttributeError: 'PatchCollection' object has no attribute 'get_offset_position'
    

    This seems to be related to the plotly issue described here: https://github.com/plotly/plotly.py/issues/3624, but I have no idea how to fix this.

    My environment looks like this:

    > pip show mplleaflet
    Name: mplleaflet
    Version: 0.0.5
    
    > pip show matplotlib
    Name: matplotlib
    Version: 3.5.1
    

    Help is much appreciated. Thanks!

    opened by pbartusch 1
  • mplleaflet AttributeError: 'XAxis' object has no attribute '_gridOnMajor'

    mplleaflet AttributeError: 'XAxis' object has no attribute '_gridOnMajor'

    mplleaflet attribute error with first use

    Problem

    • download mplleaflet v. 0.0.5 from conda-forge
    • started a test script like
    import matplotlib.pyplot as plt
    import mplleaflet
    
    long=[72.12,72.012,72.25,72.0254,73] #data (random)
    lat=[50,50.21,51.1263,52.4174,53.21]
    
    ax=plt.plot(long, lat) #matplotlib
    
    mplleaflet.display() #mplleaflet
    
    • not working; Error:
    file "C:\Anaconda\lib\site-packages\mplleaflet\mplexporter\utils.py", line 241, in get_grid_style
        if axis._gridOnMajor and len(gridlines) > 0:
    
    AttributeError: 'XAxis' object has no attribute '_gridOnMajor'
    

    Solution

    • not a big deal, just one line of code
    • solution by this

    Possible Solution

    • go to line and file from the error message (def get_grid_style)
    • change axis._gridOnMajor to axis._major_tick_kw['gridOn']
    • finish

    Setup

    • conda 4.10.3
    • python 3.8.8
    • matplotlib 3.4.2
    • mplleaflet 0.0.5
    opened by 22tommibaer01 0
  • mplleaflet is showing blank when points / features > 1000[Python Notebook]

    mplleaflet is showing blank when points / features > 1000[Python Notebook]

    I have kml file with 1000+ features and I am trying to plot via matplotlib and mplleaflet . When I tried to plot the GeoSeries with 1000+ features it shows blank whereas it works perfect when features < 1000

    I am using mplleaflet inside Python Notebook

    Here is the code :

    import mplleaflet
    import maptplotlib.pyplot as plt
    import geopandas as gpd
    
    df= gpd.read_file('xyz.kml')
    
    ax_wfs = df['geometry'][:1000].plot(figsize = (15,10) , color = 'black'  )
    mplleaflet.display(fig=ax_wfs.figure , tiles='osm' )
    

    I have also tried some stackoverflow hacks like %%capture %matplotlib inline changing alpha value to 0.1

    but unfortunately it didnt work at all . @jwass could you please help me out ? This seems like a bug

    Thanks in advance! Ash

    opened by ashutoshsoni891 1
  • Drag matplotlib patches with mouse on maps

    Drag matplotlib patches with mouse on maps

    Hello,

    I know how to drag matplotlib patches like rectangles and polygons with mouse as in the examples on this page event_handling.

    I would love to be able to do it with mplleaflet, that is to say with openstreetmaps background.

    However, I wonder if it is possible given that mplleaflet displays in web browser whereas matplotlib relies on another backend (tk by default I think) to collect events.

    If it is currently not possible, do you think there are any chance it could become possible ? or perhaps another library enables it

    Regards

    opened by deb75 0
Owner
Jacob Wasserman
Jacob Wasserman
Color maps for POV-Ray v3.7 from the Plasma, Inferno, Magma and Viridis color maps in Python's Matplotlib

POV-Ray-color-maps Color maps for POV-Ray v3.7 from the Plasma, Inferno, Magma and Viridis color maps in Python's Matplotlib. The include file Color_M

Tor Olav Kristensen 1 Apr 5, 2022
A python package for animating plots build on matplotlib.

animatplot A python package for making interactive as well as animated plots with matplotlib. Requires Python >= 3.5 Matplotlib >= 2.2 (because slider

Tyler Makaro 394 Dec 18, 2022
A python package for animating plots build on matplotlib.

animatplot A python package for making interactive as well as animated plots with matplotlib. Requires Python >= 3.5 Matplotlib >= 2.2 (because slider

Tyler Makaro 356 Feb 16, 2021
MPL Plotter is a Matplotlib based Python plotting library built with the goal of delivering publication-quality plots concisely.

MPL Plotter is a Matplotlib based Python plotting library built with the goal of delivering publication-quality plots concisely.

Antonio López Rivera 162 Nov 11, 2022
Painlessly create beautiful matplotlib plots.

Announcement Thank you to everyone who has used prettyplotlib and made it what it is today! Unfortunately, I no longer have the bandwidth to maintain

Olga Botvinnik 1.6k Jan 6, 2023
This package creates clean and beautiful matplotlib plots that work on light and dark backgrounds

This package creates clean and beautiful matplotlib plots that work on light and dark backgrounds. Inspired by the work of Edward Tufte.

Nico Schlömer 205 Jan 7, 2023
The plottify package is makes matplotlib plots more legible

plottify The plottify package is makes matplotlib plots more legible. It's a thin wrapper around matplotlib that automatically adjusts font sizes, sca

Andy Jones 97 Nov 4, 2022
A Jupyter - Leaflet.js bridge

ipyleaflet A Jupyter / Leaflet bridge enabling interactive maps in the Jupyter notebook. Usage Selecting a basemap for a leaflet map: Loading a geojso

Jupyter Widgets 1.3k Dec 27, 2022
YOPO is an interactive dashboard which generates various standard plots.

YOPO is an interactive dashboard which generates various standard plots.you can create various graphs and charts with a click of a button. This tool uses Dash and Flask in backend.

ADARSH C 38 Dec 20, 2022
Visualize data of Vietnam's regions with interactive maps.

Plotting Vietnam Development Map This is my personal project that I use plotly to analyse and visualize data of Vietnam's regions with interactive map

null 1 Jun 26, 2022
Functions for easily making publication-quality figures with matplotlib.

Data-viz utils ?? Functions for data visualization in matplotlib ?? API Can be installed using pip install dvu and then imported with import dvu. You

Chandan Singh 16 Sep 15, 2022
649 Pokémon palettes as CSVs, with a Python lib to turn names/IDs into palettes, or MatPlotLib compatible ListedColormaps.

PokePalette 649 Pokémon, broken down into CSVs of their RGB colour palettes. Complete with a Python library to convert names or Pokédex IDs into eithe

null 11 Dec 5, 2022
Insert SVGs into matplotlib

Insert SVGs into matplotlib

Andrew White 35 Dec 29, 2022
Python scripts to manage Chia plots and drive space, providing full reports. Also monitors the number of chia coins you have.

Chia Plot, Drive Manager & Coin Monitor (V0.5 - April 20th, 2021) Multi Server Chia Plot and Drive Management Solution Be sure to ⭐ my repo so you can

null 338 Nov 25, 2022
A minimal Python package that produces slice plots through h5m DAGMC geometry files

A minimal Python package that produces slice plots through h5m DAGMC geometry files Installation pip install dagmc_geometry_slice_plotter Python API U

Fusion Energy 4 Dec 2, 2022
A Python function that makes flower plots.

Flower plot A Python 3.9+ function that makes flower plots. Installation This package requires at least Python 3.9. pip install

Thomas Roder 4 Jun 12, 2022
Standardized plots and visualizations in Python

Standardized plots and visualizations in Python pltviz is a Python package for standardized visualization. Routine and novel plotting approaches are f

Andrew Tavis McAllister 0 Jul 9, 2022
Make sankey, alluvial and sankey bump plots in ggplot

The goal of ggsankey is to make beautiful sankey, alluvial and sankey bump plots in ggplot2

David Sjoberg 156 Jan 3, 2023
Plot, scatter plots and histograms in the terminal using braille dots

Plot, scatter plots and histograms in the terminal using braille dots, with (almost) no dependancies. Plot with color or make complex figures - similar to a very small sibling to matplotlib. Or use the canvas to plot dots and lines yourself.

Tammo Ippen 207 Dec 30, 2022