Render Leaflet Map from HTML (or R Leaflet Map) in Streamlit

Summary

Dissatisfied with folium map-making capabilities, so tried to make Leaflet maps in R and render them in streamlit. Thought could read in the Leaflet map as an HTML file and then render it with st.write, but having trouble getting that to work. If there was a way to render the R-map object directly in streamlit without this work-around, that would be even more ideal.

Steps to reproduce

Code snippet:

from folium import Html
import streamlit as st
import geopandas as gp

# borough data
nyboro = gp.read_file(gp.datasets.get_path("nybb"))

# save borough
nyboro.to_file("nyboro.GeoJSON", driver = "GeoJSON")

import rpy2.robjects as robjects

# import r leaflet and tmap package
import rpy2.robjects.packages as rpackages

# import R's utility package
utils = rpackages.importr('utils')

# select a mirror for R packages
utils.chooseCRANmirror(ind=1) # select the first mirror in the list

from rpy2.robjects.vectors import StrVector

packnames = ("leaflet", "tmap", "sf", "htmlwidgets")

names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]

if len(names_to_install) > 0:
    utils.install_packages(StrVector(names_to_install))

from rpy2.robjects.packages import importr

tmap = importr("tmap")
leaflet = importr("leaflet")
sf = importr("sf")
htmlwidgets = importr("htmlwidgets")

# read in dataframe as r object
nyboro_r = sf.st_read("nyboro.GeoJSON")
nyboro_r = sf.st_transform(nyboro_r, 4326)
mapnyboro_r = (tmap.tm_shape(nyboro_r) + \
    tmap.tm_polygons(
    ))

st.write(mapnyboro_r, unsafe_allow_html = True)

robjects.r('''
    nyboro = st_read("nyboro.GeoJSON")
    nyboro = st_transform(nyboro, 4326)
    nyboro = tm_shape(nyboro) +
        tm_fill(
        ) 
    nyboro = tmap_leaflet(nyboro)
    saveWidget(nyboro, "nyboro.html", selfcontained = F)
''')

html_string = open("nyboro.html").read()

# html_string

from IPython.display import display_html

from folium import Html

st.write(html_string, unsafe_allow_html = True)

# st_folium(Html(html_string))

Expected behavior:

For streamlit to render the leaflet map produced by R, whether from the raw html file or the r-leaflet object.

Actual behavior:

Streamlit renders the r-object map (mapnyboro_r) as a list-vector, and doesn’t render the html_string representing the HTML code for the leaflet map.

Other steps I’ve tried include reading the html_string with foliums Html function, and passing that to st.write and st_folium; using display_html on the html_string object; and trying to use the html function from cgitb on the html_string variable.

Debug info

  • Streamlit version: 1.13.0
  • Python version: 3.9.12
  • Conda
  • OS version: Windows 10
  • Browser version: Google Chrome

st.components.v1.html might be what you are looking for. If not, sharing the generated html would increase your chances of getting a better answer.