Set the vertical height of a figure with "height: 100vh"

Summary

Iā€™m coming from the Plotly Dash world and am attempting to take advantage of Streamlitā€™s much better ā€œdatepickerā€ widget for a simple web app.

Currently, I am attempting to make a Streamlit version of my Plotly Dash app that behaves and looks the same. The behavior is fine, itā€™s the styling that has proven challenging. Specifically, I am trying to find a way to set the styling of the Streamlit st.plotly_chart such that the resulting figure dynamically adjusts to fill the vertical space of the viewport (via something like height: 100vh).

Hereā€™s an image of the apps side by side with Dash on the left, Streamlit on the right with code bellow.

Example Code Comparison

Plotly Dash (left in image above)

import dash
from dash import dcc, html
import plotly.graph_objs as go

test_fig = go.Figure(
    data=[
        go.Scatter(
            x=[1, 2, 3, 4, 5, 6],
            y=[9, 8, 7, 6, 5, 4],
            mode='markers+lines',
            name='test'
        )
    ]
)

app = dash.Dash(__name__, title="Plotly Dash Example")

app.layout = html.Div([
    # date picker
    dcc.DatePickerRange(),
    # Figure
    dcc.Graph(
        figure=test_fig,
        style={'height': '92vh'},   # How can I do this in Streamlit?
    ),
])


if __name__ == '__main__':
    # run the Dash app
    app.run_server(debug=False)

Streamlit (right in image above)

import streamlit as st
import plotly.graph_objs as go

test_fig = go.Figure(
    data=[
        go.Scatter(
            x=[1, 2, 3, 4, 5, 6],
            y=[9, 8, 7, 6, 5, 4],
            mode='markers+lines',
            name='test'
        )
    ]
)

# create streamlit app
st.set_page_config(layout='wide')

# This section was copy pasted from other forums to reduce white space and hide header and footer
st.markdown("""
        <style>
               .css-18e3th9 {
                    padding-top: 0rem;
                    padding-bottom: 0rem;
                    padding-left: 5rem;
                    padding-right: 5rem;
                }
               .css-1d391kg {
                    padding-top: 0rem;
                    padding-right: 1rem;
                    padding-bottom: 0rem;
                    padding-left: 1rem;
                }
                #MainMenu {visibility: hidden;}
                footer {visibility: hidden;}
        </style>
        """, unsafe_allow_html=True)

date_range = st.date_input(label='Select a date range')

st.plotly_chart(test_fig, use_container_width=True)

Dash provides the ability to easily set the div height, but Iā€™m having a hard time looking through the resulting Streamlit html and css to understand what I could do with st.markdown to get the same look.

System details

  • Streamlit version: 1.16.0
  • Python version: 3.10
  • venv virtual environment

Thanks in advance!

1 Like

One way is to adjust the source or test_fig in this case.

test_fig.update_layout(
    autosize=False,
    width=400,
    height=500,
)

Thanks, @ferdy. I am aware of this mechanism for statically specifying the height / width in pixels of the Plotly fig.

But Iā€™m looking for a way to set the styling of the st.plotly_chartā€™s parent div (or whatever div needs to be set) with height: 90vh or even with a percentage like height: 90% such that the height dynamically updates with the size of the viewport or containing iframe.

Hi @jhthompson12,

Have you tried adding something like this to your st.markdown styling?

.stPlotlyChart {
    height: 90vh !important;
}

That seems to accomplish what you wanted.

2 Likes

@blackary, thank you! this is exactly what I was looking for.

Itā€™s very, very closeā€¦ The resulting visual behavior is almost identical to that of Plotly Dash:

The one difference I am noticing is that with Plotly Dash, the figureā€™s Div reacts changes in the height of the window to maintain the height: 90vh request while Streamlit seems to fix the height of the figure until page is reloaded:

  1. Change the height of both browser windows. Plotly Dash reacts and changes the figure height to fit:

  2. Reload the Streamlit window and the figureā€™s height: 90vh is applied to the new viewport size:

Do you know if thereā€™s a way to get Streamlitā€™s sizing to respond the same way as Plotly Dash?

Apologies for any asinine questions, css terrifies me. We plan to embed these simple Streamlit apps within an iframe on a different website, so I would like to have the app adjust itself to fit its containing iframe.

1 Like

@jhthompson12 You can very likely accomplish that by using one of a number of packages that let you run arbitrary javascript within your streamlit app (e.g. GitHub - aghasemi/streamlit_js_eval: A custom Streamlit component to evaluate arbitrary Javascript expressions), but Iā€™m having trouble getting a working example. Are your users commonly resizing their windows while using the app?

Thanks again, @blackary. Itā€™s possible that screen resizing could happen, but itā€™s probably not a big deal and Iā€™ll see how it goes without using more involved means of control.

Itā€™s good enough knowing that im not missing any other simple parameters to get the desired behavior.

1 Like

I have also been having trouble in Streamlit with Plotly and responsiveness. Here I tried to use streamlit_js_eval for the same purpose, maybe somebody needs it:

Itā€™s not perfect, but for me it is currently the best solution.