Aligning dataframe with plotly chart

I am attempting to use the new ‘Beta_Columns’ to have a dataframe side by side with the plotly chart. However, they are not aligned perfectly and was wondering what the best way to do that would be.

Code:
col5, col6 = st.beta_columns((1,1))
with col5:
st.dataframe(stock_recom2)
with col6:
fig = px.pie(stock_recom3, values=‘Firm’, names=‘To Grade’, title=‘Distribution by Recommendations’)
st.plotly_chart(fig, use_container_width=True)

Hey @tcbrowne,

Welcome to the Streamlit Community! :partying_face: :partying_face: :tada: :tada:

When you say that they are not aligned perfectly, do you mean that the bottom of the graph extends beyond the table on the right?

If you’re talking about how your title of the st.plotly_chart doesn’t line up with the column names from your data: I would say this is likely due to some padding on the figure itself. See the set of media I made in columns:


The tops will always line up but the bottoms are dictated by the size of the figure!

To line up the bottom: You can get around this by changing the size of one of the components in your columns, because it’s not currently supported

To line up the tops: I would remove the title from the plotly graph and put st.write('Distribution by Recommendations') before your graph!

Happy Streamlit-ing!
Marisa

Hi Marisa! Yes the bottom was the issue and your response is exactly what I was looking for. Changed the size of one of the dataframe and it looks good now. Thanks for the help!

1 Like

Awesome! So glad I can help!

@Marisa_Smith ,
I am having a very similar problem. Can you please elaborate on how to adjust the column ? Here is an example of what I am seeing:

Here is the code to regenerate what I am seeing:


# Import required libraries
import streamlit as st
import pandas as pd
import plotly.graph_objects as go

# User Defined Functions
def plotly_bar_chart(
        df: pd.DataFrame,
        x_axis_label: str = 'Month',
        y_axis_label: str = 'Monthly Value (in %)'
) -> go.Figure:
    this_chart = go.Figure(
        data=[go.Bar(x=df['Month'], y=df['Monthly_Value'], text = df['Monthly_Value'],textposition = 'auto')])
    this_chart.update_yaxes(title_text=y_axis_label)
    this_chart.update_xaxes(title_text=x_axis_label)

    return this_chart


# Start setup of the app
# Title
st.subheader("Streamlit Testing")

# Add user input widgets to the side bar
param_1 = st.sidebar.number_input(label='Random Value - 1', min_value=-90., max_value=90.)
param_2 = st.sidebar.number_input(label='Random Value - 2', min_value=-180., max_value=180.)
net = st.sidebar.number_input('Tolerance (in deg)')
start = st.sidebar.text_input('Start Date (yyyy-mm-dd)')
stop = st.sidebar.text_input('Stop Date (yyyy-mm-dd)')
completeness = st.sidebar.number_input('Completeness Filter', min_value=0., max_value=1.)

# Prepare data for plot
monthly_values = [1.2, 1.4, 2.0, 3.5, 4.7, 0.7, 1.3, 1.5, 1.5, 2.0, 2.5, 3.2]
month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
               'November', 'December']
data_dict = {'Month': month_names, 'Monthly_Value': monthly_values}
data = pd.DataFrame(data_dict)

# Prepare plot
figure, table = st.beta_columns((3, 2))
with table:
    st.write(data)
with figure:
    st.write('Monthly Rate')
    chart = plotly_bar_chart(df=data)
    st.plotly_chart(chart)

Hey @UGuntupalli,

Your graph is too large for the amount of room you gave it using the columns. You can fix this by setting the chart to be the width of your column: use_container_width = true.

Check out the docs for the plotly_chart call for more info!

Happy Streamlit-ing!
Marisa

Thanks for the prompt response @Marisa_Smith. I updated my code to reflect your suggestion, but it doesn’t still align.

"""
"""

# Import required libraries
import streamlit as st
import pandas as pd
import plotly.graph_objects as go

# User Defined Functions
def plotly_bar_chart(
        df: pd.DataFrame,
        x_axis_label: str = 'Month',
        y_axis_label: str = 'Monthly Value (in %)'
) -> go.Figure:
    this_chart = go.Figure(
        data=[go.Bar(x=df['Month'], y=df['Monthly_Value'], text = df['Monthly_Value'],textposition = 'auto')])
    this_chart.update_yaxes(title_text=y_axis_label)
    this_chart.update_xaxes(title_text=x_axis_label)

    return this_chart


# Start setup of the app
# Title
st.subheader("Streamlit Testing")

# Add user input widgets to the side bar
param_1 = st.sidebar.number_input(label='Random Value - 1', min_value=-90., max_value=90.)
param_2 = st.sidebar.number_input(label='Random Value - 2', min_value=-180., max_value=180.)
net = st.sidebar.number_input('Tolerance (in deg)')
start = st.sidebar.text_input('Start Date (yyyy-mm-dd)')
stop = st.sidebar.text_input('Stop Date (yyyy-mm-dd)')
completeness = st.sidebar.number_input('Completeness Filter', min_value=0., max_value=1.)

# Prepare data for plot
monthly_values = [1.2, 1.4, 2.0, 3.5, 4.7, 0.7, 1.3, 1.5, 1.5, 2.0, 2.5, 3.2]
month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
               'November', 'December']
data_dict = {'Month': month_names, 'Monthly_Value': monthly_values}
data = pd.DataFrame(data_dict)

# Prepare plot
figure, table = st.beta_columns((3, 2))
with table:
    st.write(data)
with figure:
    st.write('Monthly Rate')
    chart = plotly_bar_chart(df=data)
    st.plotly_chart(chart, use_container_width=True)

Hi @UGuntupalli,

You’re looking for alignment at the top of your columns? When you added the screenshot of the bottom of your columns I thought you were looking for a solution to the fact that your columns were overlapping.

From above:

So the reason the top of your data frame and your graph are not lined up is that you have an st.write() statement in your columns before you call your plotly_chart. If you move this outside your column the top of your columns will line up with one another!

@Marisa_Smith,
This is getting a little confusing. Let me see if I can explain what I am seeing and perhaps you can help move in the right direction:

Tops always line up - Top is also not lining up in my case, even after I uncomment st.write(), please see below:

figure, table = st.beta_columns((3, 2))
# st.write('Monthly Rate')
with table:
    st.write(data)
with figure:
    chart = plotly_bar_chart(df=data)
    st.plotly_chart(chart, use_container_width=True)

I basically want them to align side by side (both top and bottom) similar to this example shown in the documentation, but even here, they are a little off where the top is not aligned.

Additionally, I noticed that this does not happen if I use Altair Charts. I think this is a problem that arises when we use Plotly with Streamlit.

Bump - Looking for any clarification on the topic

1 Like

Hey @UGuntupalli,

Apologies it’s been busy, thanks for the bump reminder!

RIGHT! ok so! Thanks for clarifying that. I’m going to break your questions down slightly out of order to try and help illuminate what’s happening here :bulb:

Ok so this is actually an artifact of the layout not being in “widemode”, the second column subheader then ends up wrapping around to the second line and this causes the dataframe to be out of line with the graph. If you actually set the page configuration to be wide then they line up perfectly:

Here is where my answer gets annoying (blame Plotly, not the messenger! :rofl:).

Your two columns actually are lined up, it just doesn’t look that way because there is so much white headspace created in a plotly graph (where they store all the interactive parts of the graph). So I made an app to help demo what I mean here. I made an app with 3 columns, a plotly graph, data and then the same data in a line graph. The tops do align, in fact, to help illustrate this point I coloured the plotly background in grey and you can see the top of the grey does actually line up with the top of the others.

Hope this clears things up for you!
Happy Streamlit-ing!
Marisa