Can't adjust dataframes decimal places

I have a dataframe with integer and float columns like so:

And as you can see, some values in the Days_to_Sell column have no decimal places, while others have 4. In order to try and have some sorts of consistency, I want to use only 2 decimal places. In order to achieved that, I use the panda’s round function like so:

st.dataframe(df_display.round(2))

But got the same result.

Is there anyway I can change the number of decimal places besides using .round, that actually works with streamlit?

4 Likes

Use pandas Styles. https://docs.streamlit.io/api.html?highlight=style#streamlit.dataframe

Hey @marciorpcoelho,

As @knorthover pointed out, you can pass pandas Styler to style your dataframe, most notably how to change the display of values.

The following works :

df = pd.DataFrame(
   np.random.randn(50, 20),
   columns=('col %d' % i for i in range(20))
)

st.dataframe(df.style.format("{:.2%}"))

4 Likes

Thank you for your help. From my original dataframe:

I tried to implement a style on the last three columns, like so:

df.style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.1f}'})

But notice how it didn’t make any change, aside from the 1.199.2 value:

So fater adjusting the style like:

df..style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.2f}'})

This is what I got:

Which is still far from my goal which is 1, 2 and 1 decimal place in Quantidade, PVP and Dias de Venda columns, respectively.

Does anyone know the reason for this apparent erratic behavior?

Hi @marciorpcoelho,

Can you try this sample code and let me know if it works for you?

import numpy as np
import pandas as pd

import streamlit as st

np.random.seed(24)
df = pd.DataFrame({"A": np.linspace(1, 5, 5)})
df = pd.concat([df, pd.DataFrame(np.random.randn(5, 4), columns=list("BCDE"))], axis=1)
df.iloc[0, 2] = np.nan

# Unstyled
st.table(df)

# Custom formatting
st.table(df.style.format({"E": "{:.2f}"}))

If that works fine, can you provide sample code so we can reproduce your issue on our end?

2 Likes

Thank you for your reply. Using your example, it worked as intended:

But when I applied to my case with:

st.table(df.style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.2f}'}))

This is the result I got:
´

The decimal place is still inconsistent throught the columns. Not to mention that I avoided using st.table, due to the lack of limit in the number of row’s output.

Hey @marciorpcoelho - could you provide sample code that demonstrates your issue, so we can help you track it down?

I had already shown some code I was using, but sure, here’s a full working example:

import streamlit as st
import pandas as pd

part_refs = ['AM85.45.2.545.505', 'AM85.45.2.545.506', 'AM85.45.2.547.501',
             'AM85.45.2.548.070', 'AM85.45.2.548.314', 'AM85.45.2.548.315',
             'AM85.45.2.593.502', 'AM85.45.2.593.784', 'AM85.45.2.593.789',
             'AM85.45.2.593.872']
quantities = [2.0, 2.0, 8.0, 1.0, 2.0, 1.0, 1.0, 3.0, 1.0, 2.0]
pvps = [98.5, 94.0, 134.0, 176.5, 187.5, 214.5, 304.0, 246.0, 177.95, 254.4]
days_to_sell = [7.0, 7.0, 1.75, 12.5, 7.0, 9.0, 8.0, 5.0, 14.0, 7.5]
df = pd.DataFrame({'Referência': part_refs, 'Quantidade': quantities, 'PVP': pvps, 'Dias de Venda': days_to_sell})

# Unstyled
st.dataframe(df)

# Styled
st.dataframe(df.style.format({'Quantidade': '{:.1f}', 'PVP': '{:.2f}', 'Dias de Venda': '{:.2f}'}))

Which produce the following results:

1 Like

Thanks! It’s always useful to have a full test case, to ensure everyone’s looking at exactly the same data and code.

I’ve tracked down the cause of the issue and opened a bug here. The fix is potentially very simple but involves a bandwidth tradeoff - we’ll discuss it as a team and figure out the best way to get this taken care of! Thanks for helping us figure this out.

4 Likes

Ah ok, thanks for the info.
Just glad I could help in finding the bug!

Try with below:

st.write(df.style.format("{:.2}"))

Or

st.DataFrame(df.style.format("{:.2}"))

Thanks for the help but I had already tried this method for testing purposes. The problem is that I wanted to specify different decimal cases for each column.

Olá, Marcio
use “.set_precision(2)” no styler.

For those who see this issue in the future:

Just add .set_precision(2) to your styler

This solution seems to be more functional

Check this examples for a dataframe called ‘tabela’
st.dataframe(tabela.style.background_gradient(cmap=‘Greens’).set_precision(2),height=500)

5 Likes

Thanks for your reply Andre_Holanda, but would your solution allow me to customize the number of decimal places per column instead of a applying a precision of 2 decimal places across all dataframe?

1 Like

Here you go:
The trick is just to display the streamlit object dataframe with 2 Decimal by

st.write(dataframe.style.format({ ‘Name of Column you want to specify’: ‘{:.2f}’})

this worked for me. Let me know if this was helpful!

Here you go:
The trick is just to display the streamlit object dataframe with 2 Decimal by

st.write(dataframe.style.format({ ‘ Name of Column you want to specify ’: ‘{:.2f}’})

this worked for me. Let me know if this was helpful!

Used the same trick but now instead of decimals the value are changed to this… Does anyone know why this is happening?

1 Like

Can you please give us some minimum code example that causes your problem?

We just released a large set of configuration options and column types for st.dataframe and st.data_editor in 1.23. This also allows to configure the number format via the NumberColumn and thereby adjust the decimal places:

st.dataframe(
    pd.DataFrame({"A": [1.1234, 2.345678], "B": [3.45678, 4.56789]}),
    column_config={"A": st.column_config.NumberColumn(format="%.2f")}
)

As an alternative, you can also use the step size to adapt the precision of the number which will also have impact on how many decimals are shown and will limit the number of decimals a user can input when used with st.data_editor:

st.data_editor(
    pd.DataFrame({"A": [1.1234, 2.345678], "B": [3.45678, 4.56789]}),
    column_config={"A": st.column_config.NumberColumn(step=0.01)},
)

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.