I am trying to display a folium
map in a card in a shiny for Python
app using the code below (Reproducible example):
from shiny import App, ui, render, reactive
import folium
app_ui = ui.page_fluid(
ui.tags.style(
"""
/* apply css to control height of some UI widgets */
.map-container {
height: 700px !important;
width: 100%;
overflow: hidden;
}
.map-container > * {
height: 100% !important;
}
"""
),
ui.column(6,
ui.navset_card_tab(
ui.nav_panel("Map",
ui.div(
ui.output_ui("map"),
class_="map-container"
)
),
ui.nav_panel("Data",
ui.p(
ui.output_table("data_table")
)
)
)
)
)
def server(input, output, session):
@output
@render.ui
def map():
m = folium.Map(location=[51.509865, -0.118092], zoom_start=12)
return ui.HTML(m._repr_html_())
@output
@render.table
def data_table():
# Your data table rendering logic here
pass
app = App(app_ui, server)
I want the element containing the map to fill the height of my screen but my the map itself is refusing to fill the whole height of the card. It is only occupying the upper half of the card area.
In Shiny for R
, I had achieved the same result using the as_fill_carrier()
function from the bslib
library like this:
card(
style = "height: 80vh;",
full_screen = TRUE,
#card_header("Map"),
card_body(
tmapOutput("map") %>%
withSpinner(type = 6, color = "#30804e") %>% as_fill_carrier()
)
)
)
What can I do?
This is an issue with folium
, where m._repr_html_()
causes the map to be embedded within a div
which has padding-bottom: 60%;
by default. This has to be overwritten if you want to use the whole space. Below is an example where this is done by just replacing the css
with more suitable one, in particular, I remove the padding-bottom: 60%;
and apply height: 100%;
which yields the desired filling layout.
from shiny import App, ui, render
import folium
app_ui = ui.page_fluid(
ui.tags.style(
"""
/* apply css to control height of some UI widgets */
.map-container {
height: 700px !important;
width: 100%;
overflow: hidden;
}
.map-container > * {
height: 100% !important;
}
"""
),
ui.column(6,
ui.navset_card_tab(
ui.nav_panel("Map",
ui.div(
ui.output_ui("map"),
class_="map-container"
)
),
ui.nav_panel("Data",
ui.p(
ui.output_table("data_table")
)
)
)
)
)
def server(input, output, session):
@output
@render.ui
def map():
m = folium.Map(location=[51.509865, -0.118092], zoom_start=12)
m = m._repr_html_()
m = m.replace(
'<div style="width:100%;"><div style="position:relative;width:100%;height:0;padding-bottom:60%;">',
'<div style="width:100%; height:100%;"><div style="position:relative;width:100%;height:100%;>',
1)
return ui.HTML(m)
@output
@render.table
def data_table():
# Your data table rendering logic here
pass
app = App(app_ui, server)