:param title: Title of the Streamlit app.
:param description: Description of the Streamlit app.
"""
self.title = title
self.description = description
def render_title(self):
"""
Render the title of the app.
"""
st.title(self.title)
def render_description(self):
"""
Render the description of the app.
"""
st.write(self.description)
def render_file_uploader(self, label="Upload a file", file_types=["csv", "xlsx"]):
"""
Render a file uploader and return the uploaded file.
:param label: Label for the file uploader.
:param file_types: List of allowed file types.
:return: Uploaded file.
"""
uploaded_file = st.file_uploader(label, type=file_types)
return uploaded_file
def read_file(self, uploaded_file):
"""
Read the uploaded file into a Pandas DataFrame.
:param uploaded_file: Uploaded file.
:return: DataFrame containing the file data.
"""
if uploaded_file.name.endswith('.csv'):
df = pd.read_csv(uploaded_file)
elif uploaded_file.name.endswith('.xlsx'):
df = pd.read_excel(uploaded_file)
else:
st.error("Unsupported file format!")
return None
return df
def render_dataframe(self, df):
"""
Render a Pandas DataFrame in the app.
:param df: DataFrame to render.
"""
st.dataframe(df)
def render_sidebar(self, df):
"""
Render the sidebar with user input options.
:param df: DataFrame to be used for sidebar options.
:return: User selected options from sidebar.
"""
st.sidebar.title("Options")
chart_type = st.sidebar.selectbox("Select Chart Type", ["Line Chart", "Bar Chart", "Scatter Plot"])
x_axis = st.sidebar.text_input("X-axis Column")
y_axis = st.sidebar.text_input("Y-axis Column")
columns = st.sidebar.multiselect("Select Columns", options=df.columns.tolist())
date_column = st.sidebar.selectbox("Select Date Column", options=["None"] + df.columns.tolist())
date_range = st.sidebar.date_input("Select Date Range", [])
search_term = st.sidebar.text_input("Search Term")
return chart_type, x_axis, y_axis, columns, date_column, date_range, search_term
def filter_data(self, df, date_column, date_range, search_term):
"""
Filter data based on date range and search term.
:param df: DataFrame to filter.
:param date_column: Column to use for date filtering.
:param date_range: Date range for filtering.
:param search_term: Search term for filtering.
:return: Filtered DataFrame.
"""
if date_column != "None" and date_range:
start_date, end_date = date_range
df = df[(df[date_column] >= pd.to_datetime(start_date)) & (df[date_column] <= pd.to_datetime(end_date))]
if search_term:
df = df[df.apply(lambda row: row.astype(str).str.contains(search_term, case=False).any(), axis=1)]
return df
def render_plot(self, df, chart_type, x_axis, y_axis):
"""
Render a plot from a DataFrame.
:param df: DataFrame to plot.
:param chart_type: Type of chart to plot.
:param x_axis: Column name for the x-axis.
:param y_axis: Column name for the y-axis.
"""
if x_axis not in df.columns or y_axis not in df.columns:
st.error("Invalid columns for plotting. Please check the column names.")
return
plt.figure(figsize=(10, 6))
if chart_type == "Line Chart":
sns.lineplot(data=df, x=x_axis, y=y_axis)
elif chart_type == "Bar Chart":
sns.barplot(data=df, x=x_axis, y=y_axis)
elif chart_type == "Scatter Plot":
sns.scatterplot(data=df, x=x_axis, y=y_axis)
plt.title(f"{chart_type} of {y_axis} vs {x_axis}")
st.pyplot(plt)
def render_download_button(self, df, label="Download data as CSV", file_name="data.csv"):
"""
Render a download button for the DataFrame.
:param df: DataFrame to download.
:param label: Label for the download button.
:param file_name: Default file name for the download.
"""
csv = df.to_csv(index=False).encode('utf-8')
st.download_button(label=label, data=csv, file_name=file_name, mime='text/csv')
def run(self):
"""
Run the Streamlit app.
"""
self.render_title()
self.render_description()
# Render file uploader and read the uploaded file
uploaded_file = self.render_file_uploader()
if uploaded_file is not None:
df = self.read_file(uploaded_file)
if df is not None:
# Display the data frame
self.render_dataframe(df)
# Render sidebar and get user inputs
chart_type, x_axis, y_axis, columns, date_column, date_range, search_term = self.render_sidebar(df)
# Filter data based on user inputs
df_filtered = self.filter_data(df, date_column, date_range, search_term)
# Display the filtered data frame
self.render_dataframe(df_filtered)
# Render plot based on user inputs
if x_axis and y_axis:
self.render_plot(df_filtered, chart_type, x_axis, y_axis)
# Render download button for the filtered data
self.render_download_button(df_filtered)