Skip to content

Altair chart width regression for Layered component inside VConcat #13974

@Kaan191

Description

@Kaan191

Checklist

  • I have searched the existing issues for similar issues.
  • I added a very descriptive title to this issue.
  • I have provided sufficient information below to help reproduce this issue.

Summary

PR #13423 introduces a regression where alt.vconcat . The PR was made to address issue #13410. This introduced a breaking change when I upgrade Streamlit from version 1.52.2 to 1.53.0 (and up).

Before upgrading, my use case involved having a bar chart with text layered on top of it be the top element of a VConcat, along with another bar chart at the bottom. I discovered that using autosize="fit-x" helped align the widths of the two charts along its width.

After the upgrade, I noticed that chart stopped rendering. Because I manually included autosize in my chart using alt.vconcat.properties, the code introduced by PR #13423 did not change that aspect of the vega-lite spec produced. However, when comparing the view source code of the charts using the different versions of Streamlit (1.52.2 vs 1.53.0), I noticed that the "width" key of the broken spec reverted to a fixed width that I specified in the chart properties, while the bottom didn't. When using the Vega Editor to change the width of the top (layered) chart and make it equal to the bottom chart, a render would re-appear.

Analysing PR #13423, I believed it was lines 161-168 in frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.ts that broke my chart. This code appears to prevent the setting of the width of a child to that of the container width (when using st.altair_chart(chart, width="stretch") when that child is one of "hconcat", "vconcat", "concat", "layer".

What I don't understand is why exactly this code was inserted. When I build Streamlit from source, comment out those lines, I have fixed the regression that I experienced. At the same time, I don't see any difference in how the example provided by @connortann in issue #13410 is rendered. Is more testing required?

Reproducible Code Example

# saved as ~/test.py

import altair as alt
import streamlit as st
import pandas as pd
from numpy.random import default_rng

df = pd.DataFrame(default_rng(0).standard_normal((60, 2)), columns=["a", "b"])
base = alt.Chart(df).mark_circle().encode(x="a", y="b").properties(width=400, height=200)
text = base.mark_text(dy=-10).encode(text=alt.Text("b:Q", format=".1f"))

with st.echo():
    st.header('original issue #13410 (VConcat & HConcat)')
    st.caption('With lines 161-168 commented out, it renders exactly the same as is')
    chart = base & (base | base)
    st.altair_chart(chart, width='stretch')

with st.echo():
    # PR #13423 ensures that vega-lite spec defaults to
    # "autosize": {"type": "pad", "contains": "padding"}.
    # The overrun issue persists...
    st.header('My issue (Layered & VConcat) without autosize=fit-x')
    st.caption('As is, the top (layered) chart reverts to 400 width and the bottom chart flows out the container')
    st.caption('With lines 161-168 commented out, it renders but the charts flow out of the container')
    chart = (base + text) & base
    st.altair_chart(chart, width='stretch')

with st.echo():
    # Manually controlling the "autosize" spec produced the desired behavior up
    # until streamlit version 1.52.2 (until PR #13423 was introduced).
    # Commenting out lines 161-168 in
    # `frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.ts`
    # Fixes this issue when I build `streamlit` on my system runing the React development server
    st.header('My issue (Layered & VConcat) with autosize=fit-x')
    st.caption('As is, the chart does not render')
    st.caption('With lines 161-168 commented out, it produces the desired chart')
    chart = (base + text) & base
    chart = chart.properties(autosize='fit-x')
    st.altair_chart(chart, width='stretch')

Steps To Reproduce

  1. Build Streamlit from source
  2. Run React development server
  3. Save reproducible code example to home directory
  4. In another terminal window, run uv run streamlit run ~/test.py
  5. Note how the third chart does not render
  6. Comment out the following lines (161-168) from frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.ts:
if (
    "hconcat" in child ||
    "vconcat" in child ||
    "concat" in child ||
    "layer" in child
) {
    return
}

Expected Behavior

The running streamlit application hot-reloads and the third chart renders as expected.

Current Behavior

Without commenting out the lines in frontend/lib/src/components/elements/ArrowVegaLiteChart/useVegaElementPreprocessor.ts, the third chart does not render

Is this a regression?

  • Yes, this used to work in a previous version.

Debug info

  • Streamlit version: 1.53.0
  • Python version: 3.13
  • Operating System: MacOS 15.7.3
  • Browser: Safari

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature:chartsRelated to charting functionalityfeature:st.altair_chartRelated to the `st.altair_chart` elementfeature:st.vega_lite_chartRelated to the `st.vega_lite_chart` elementpriority:P3Medium prioritystatus:confirmedBug has been confirmed by the Streamlit teamtype:bugSomething isn't working as expectedtype:regressionThis bug is a regression from previous behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions