Center Streamlit Button - python

How do I center a button with Streamlit so that the button is still clickable? Here is a small example for a button that returns random numbers:
import streamlit as st
import numpy as np
if st.button('Click'):
rand = np.random.standard_normal()
st.write(str(rand))
I've seen solutions with markdown for a title, but not for an interactive element like a button.

Right now that’s not supported in Streamlit, but we are working on it (see our Roadmap for more info).
Feel free to add your ideas to Customizable Layout for Streamlit discussion.
And thanks for using Streamlit!

col1, col2, col3 = st.beta_columns(3)
if col2.button('Click'):
st.write('hello')

As far as I know there is no standard way to align the button in the center. I have however found a quick fix. It's not the right way but does the job.
You can try out :
col1, col2, col3 , col4, col5 = st.beta_columns(5)
with col1:
pass
with col2:
pass
with col4:
pass
with col5:
pass
with col3 :
center_button = st.button('Button')
The following will create 5 columns and you can center your button in the third one while the other 4 remain empty. This is just a quick fix and not the correct way however it did the job for me.
Hope you liked it.

TL;DR;
import streamlit as st
st.markdown("----", unsafe_allow_html=True)
columns = st.columns((2, 1, 2))
button_pressed = columns[1].button('Click Me!')
st.markdown("----", unsafe_allow_html=True)
You will get the following result (if default: narrow streamlit page settings):
Streamlit columns
Streamlit docs defines columns() in the following way:
columns = st.columns(spec)
where specs are either int or a list (or a tuple). For example, st.columns([3, 1, 2]) creates 3 columns where the first column is 3 times the width of the second, and the last column is 2 times that width. Hence, you may play around with their relative width.
What is more useful, you will get a list of columns, so you may address them as consequent numbers. You may use that in case of flexible numbers of columns:
import streamlit as st
import random
column_qty = random.randint(1, 10) # random number of columns on each run
buttons_pressed = [] # here we will collect widgets
st.markdown("----", unsafe_allow_html=True)
# create all columns with arbitrary relative widths
columns = st.columns([random.randint(1, 3) for _ in range(column_qty)])
# Show widgets in them
for x, col in enumerate(columns):
# if you need a static widget, just use: `col.text("some text")`
buttons_pressed.append(col.checkbox(f'{x}')) # add widgets to the list
st.markdown("----", unsafe_allow_html=True)
st.text(f'Total columns: {column_qty}')
# Check each widget for its state
for x, btn in enumerate(buttons_pressed):
if btn:
st.write(f"{x}") # NOTE: some columns may be dropped next run!
A very useful thing for flex input forms.

Use:
_, _, _, col, _, _, _ = st.columns([1]*6+[1.18])
clicked = col.button('Button')

To create 3 columns, pick the center one and add a button to it, you can use:
import streamlit as st # 1.18.1
if st.columns(3)[1].button("click me"):
st.write("clicked")
This doesn't center the button within the column, though, so hacking the CSS seems to be a current option, but I suspect the classes aren't reliable:
style = "<style>.row-widget.stButton {text-align: center;}</style>"
st.markdown(style, unsafe_allow_html=True)
with st.empty():
if st.button("click me"):
st.button("clicked!")
Another centering approach, following existing answers, is to force the button's container to be smaller so it takes up most or all of the space in it, functionally centering it:
col = st.columns(7)[3] # use an odd number and pick the middle element
clicked = col.button("click me")
Better than that might be to keep 3 columns, but make the first and last large and fit the middle one roughly to the button size. Adjust to taste:
col = st.columns((3, 1, 3))[1] # adjust to taste, possibly using floats
clicked = col.button("click me")
Removing the flex property with custom CSS might help make this robust to different screen sizes so the button text doesn't squish when shrunk.
None of these approaches are entirely satisfactory, so I'm curious to hear any new developments.
See also How to center the title and an image in streamlit?.

Related

Color or highlight each duplicate in a column with different color with pandas - python

I would like to highlight duplicates in a column so its easier to the eye to spot them out. Not really sure how I should do this as the numbers might change now and then based on import data.
I manage to highlight the duplicates with this code but its terrible colors and it seems impossible to change color-palette(?)
colors = dict(zip(unique_fraud['IMSI'].unique(),
(f'background-color: {c}' for c in plt.colors.cnames.values())))
unique_fraud.style.applymap(colors.get, subset=['IMSI'])
My data looks like this at the moment
Picture of column
Could anyone help me with a code that works or if its possible to change palette with my current code? thanks
colors = dict(zip(unique_fraud['IMSI'].unique(), (f'background-color: {c}' for c in plt.colors.cnames.values()))) unique_fraud.style.applymap(colors.get, subset=['IMSI'])
solution is to delete plt.colors.cnames.values() and add a custom_color variable such as this
``custom_color = ["#12345", "#CC4AAD", "other colorcodes"]

IPython / Jupyter: how to customize the display function

I have 3 basic problems when displaying things in IPython / JupyterLab.
(1) I have a pandas dataframe with many columns. First, I make sure I can see a decent portion of it:
import numpy as np
import pandas as pd
np.set_printoptions(linewidth=240,edgeitems=5,precision=3)
pd.set_option('display.width',1800) #number of pixels of the output
pd.set_option('display.max_columns',100) #replace the number with None to print all columns
pd.set_option('display.max_rows',10) #max_columns/max_rows sets the maximum number of columns/rows displayed when a frame is pretty-printed
pd.set_option('display.min_rows',9) #once max_rows is exceeded, min_rows determines how many rows are shown in the truncated representation
pd.set_option('display.precision',3) #number of digits in the printed float number
If I print it, everything gets mushed together:
enter image description here
Is it possible to print text wide, i.e. in a way that each line (even if longer) is printed on only 1 line in output, with a slider when lines are wider than the window?
(2) If I display the mentioned dataframe, it looks really nice (has a slider), but some string entries are displayed over 4 rows:
enter image description here
How can I make sure every entry is displayed in 1 row?
(3) The code below produces the output, which works fine:
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0.1,30,1000);
fig,ax=plt.subplots(1, 4, constrained_layout=True, figsize=[15,2])
ax=ax.ravel()
ax[0].plot( x, np.sin(x))
ax[1].plot( x, np.log(1+x))
ax[2].plot( x, np.sin(30/x))
ax[3].plot( x, np.sin(x)*np.sin(2*x))
plt.show()
enter image description here
However, when I change [15,2] to [35,2], the figure will only be as wide as the window. How can I achieve that larger widths produce a slider (like display of a dataframe) so that I can make images as wide as I wish?
You solved (1) already by deciding to display the dataframe with the method in (2). Using print to display a dataframe is not very useful in my opinion.
(2): The display(df) automatically utilizes white spaces to wrap cell content. I did not find a pandas option to disable this behavior. Luckily, someone else had the same problem already and another person provided a solution.
You have to change the style properties of your dataframe. For this you use the Styler, which holds the styled dataframe. I made a short example from which you can copy the line:
import pandas as pd
# Construct data frame content
long_text = 'abcabcabc ' * 10
long_row = [long_text for _ in range(45)]
long_table = [long_row for _ in range(15)]
# Create dataframe
df = pd.DataFrame(long_table)
# Select data you want to output
# df_selected = df.head(5) # First five rows
# df_selected = df.tail(5) # Last five rows
df_selected = df.iloc[[1,3, 7]] # Select row 1,3 and 7
# Create styler of df_selected with changed style of white spaces
dataframe_styler = df_selected.style.applymap(lambda x:'white-space:nowrap')
# Display styler
display(dataframe_styler)
Output:
(3) As I already mentioned in the comment, you simply have to double click onto the diagram and it is displayed with a slider.

Streamlit selectbox is reseting the webpage

I am currently trying to use the selectbox to allow the users to pick a name of a column to run a model with. When I put a selectbox in the sidebar I didn’t have an issue, but when I put the selectbox on the main page as soon as the user selects a option the wepage resets. the code is below. I am still new to streamlit, so I am not sure if I am using this properly. I appreciate the help!
#add a blank space in the columnName section
columnNames = [" "]
#grab the column names of the dataframe
for column in df.columns:
columnNames.append(column)
#place the selectboxe in the col1 slot
with col1:
#display the column names to the user
#So that they can select the columns they want to use
columnValue = st.multiselect("Select the column:", columnNames)
#place a button in col2 slot
with col2:
#a button to add the selected column to a list of want to use columns
addButtonList = st.button("Add to select list: ")
#when 'addButtonList' is selected take the value from
#'columnValue' and place it on the screen.
if(addButtonList):
st.write(columnValue)
There seems to be a way by setting the session_state to the button. Check this https://discuss.streamlit.io/t/the-button-inside-a-button-seems-to-reset-the-whole-app-why/1051 OR https://gist.github.com/tvst/faf057abbedaccaa70b48216a1866cdd for the detailed explanation.

How to set a color for a specific row in pandastable, using python 3.7

I have created a simple pandastable form in python, but I have some problems getting the rows in colors.
I have tried the following definition from the documentation, but it does not seem to work?
pt.setRowColors(rows=rows1, clr="red")
Here is my code:
# pandas as pt
# rows1 is a list of rows i would like to color
app = tk.Tk()
f = tk.Frame(app)
f.pack(fill=tk.BOTH,expand=1)
pt = Table(f, dataframe=myData, showtoolbar=False, showstatusbar=False)
pt.show()
pt.setRowColors(rows=rows1, clr="red")
pt.redraw()
I wanted 30 rows to have a red background, but it does nothing. I do not even get an error to go by...
Hope you can help.
The pandastable API docs suggest you should use a Hex value for the colour:
setRowColors(rows=None, clr=None, cols=None)[source]
Set rows color from menu. :param rows: row numbers to be colored :param clr: color in hex :param cols: column numbers, can also use ‘all’
So, according to this, the following should color all rows red in row1:
setRowColors(rows=rows1, clr='#FF0000', cols=None)

Create cumsum column with Python Script Widget in Orange

I can't create one new column with the cumulative sum of another.
Orange documentation is to hard to understand if you are new to Python like me.
This is the code i have in my Python Script Widget
import numpy as np
## make a copy from the data that widget recieves
out_data = in_data.copy()
## compute cumulative sum of column values
newCumsumColValues = np.cumsum(out_data[:,('myCumsumcolTarget')])
## i got the values
print(newCumsumColValuesl)
## i need to create a new column with the values in out_data
## i've tried to update column values first to test
## with an static value column values updated to 8
out_data[:,'myCumsumcolTarget'] = 8
## with newCumsumColValue is NOT working
out_data[:,'myCumsumcolTarget'] = newCumsumColValues
These examples are hard to understand for me:
https://docs.orange.biolab.si/3/visual-programming/widgets/data/pythonscript.html
https://docs.orange.biolab.si/3/data-mining-library/tutorial/data.html#exploration-of-the-data-domain
Thanks in advance,
Vince.
Try:
out_data.X[:, i] = newCumsumColValues
where i is
out_data.domain.index(out_data.domain['myCumsumcolTarget'])
This code is a bit complicated but it works.

Categories