> ## Documentation Index
> Fetch the complete documentation index at: https://fastapi2day.codewithsiva.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with Data, Charts, and Caching in Streamlit

> Load CSV files, display and filter Pandas DataFrames, run NumPy calculations, and render Matplotlib charts inside your Streamlit app.

Streamlit's primary use case is turning data workflows into interactive apps, which means integrating tightly with Pandas, NumPy, and Matplotlib is central to almost everything you'll build. This chapter shows you how to load data efficiently with caching, display and filter DataFrames, perform quick NumPy calculations, and render charts — all inside a Streamlit app. By the end you'll have the core patterns needed to build fully interactive data exploration tools.

## Loading CSV Data

The standard approach is to read your CSV with Pandas inside a cached function. The `@st.cache_data` decorator tells Streamlit to run the function only **once**, then store the result in memory. On subsequent reruns (triggered by widget interactions), Streamlit returns the cached DataFrame instantly instead of re-reading the file.

```python theme={null}
import streamlit as st
import pandas as pd

@st.cache_data
def load_data():
    return pd.read_csv("data/sales.csv")

sales = load_data()
st.dataframe(sales.head())
```

Without caching, every widget interaction would re-read and re-parse your CSV from disk — noticeably slow for large files.

### Handling Uploaded Files

When you want users to bring their own data, combine `st.file_uploader` with `pd.read_csv`:

```python theme={null}
import streamlit as st
import pandas as pd

uploaded = st.file_uploader("Upload a CSV file", type="csv")

if uploaded is not None:
    df = pd.read_csv(uploaded)
    st.success(f"Loaded {len(df):,} rows and {len(df.columns)} columns.")
    st.dataframe(df)
else:
    st.info("Please upload a CSV file to get started.")
```

## Displaying DataFrames

```python theme={null}
import streamlit as st
import pandas as pd

monthly = pd.DataFrame({
    "Month": ["January", "February", "March", "April"],
    "Sales": [120_000, 180_000, 150_000, 220_000],
    "Region": ["North", "South", "North", "East"]
})

st.subheader("Monthly Sales Overview")
st.dataframe(monthly)               # Interactive — sortable, scrollable
st.table(monthly[["Month", "Sales"]])  # Static display
```

## Filtering DataFrames with Widgets

Combining Pandas filters with Streamlit widgets is the heart of interactive data apps. User selections from widgets become filter conditions on your DataFrame:

```python theme={null}
import streamlit as st
import pandas as pd

products = pd.DataFrame({
    "Product": ["Phone", "Laptop", "Headphones", "Tablet"],
    "Region":  ["North", "South", "North", "East"],
    "Sales":   [100_000, 200_000, 50_000, 80_000]
})

# Widget inputs
search = st.text_input("Search product name")
region = st.selectbox("Filter by region", ["All", "North", "South", "East"])

# Apply filters
filtered = products[
    products["Product"].str.contains(search, case=False, na=False)
]
if region != "All":
    filtered = filtered[filtered["Region"] == region]

st.dataframe(filtered)
st.caption(f"Showing {len(filtered)} of {len(products)} products")
```

## NumPy Calculations

NumPy integrates naturally into Streamlit. You can display NumPy outputs with `st.write()` or use them to feed charts:

```python theme={null}
import streamlit as st
import numpy as np

values = np.array([10, 25, 38, 47, 55, 61, 72, 88])

col1, col2, col3 = st.columns(3)
col1.metric("Sum",  int(values.sum()))
col2.metric("Mean", round(float(values.mean()), 1))
col3.metric("Std",  round(float(values.std()),  1))

st.write("Sorted values:", np.sort(values))
```

## Rendering Matplotlib Charts

Streamlit renders Matplotlib figures with `st.pyplot(fig)`. Always create the figure explicitly using the object-oriented interface (`fig, ax = plt.subplots()`) to avoid state leakage between reruns.

```python theme={null}
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt

sales = pd.DataFrame({
    "Month": ["Jan", "Feb", "Mar", "Apr", "May"],
    "Sales": [120, 180, 150, 220, 195]
})

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(sales["Month"], sales["Sales"], marker="o", color="#3B82F6", linewidth=2)
ax.set_title("Monthly Sales Trend")
ax.set_xlabel("Month")
ax.set_ylabel("Sales (₹ thousands)")
ax.grid(True, alpha=0.3)

st.pyplot(fig)
```

<Note>
  Always pass the `fig` object explicitly to `st.pyplot(fig)`. Calling `st.pyplot()` without an argument (using the global Matplotlib state) is deprecated and can produce unexpected charts as your app grows.
</Note>

## Interactive Data Exploration Pattern

This pattern combines filtering widgets, a filtered DataFrame display, and a chart into a reusable template:

```python theme={null}
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt

@st.cache_data
def load_data():
    return pd.DataFrame({
        "Product":   ["Phone", "Laptop", "Headphones", "Tablet", "Monitor"],
        "Sales":     [100, 200, 50, 80, 150],
        "Rating":    [4, 5, 3, 4, 5],
        "Department": ["Electronics"] * 5
    })

df = load_data()

st.title("Product Performance")

# Filters
min_rating = st.slider("Minimum rating", 1, 5, 3)
show_chart = st.checkbox("Show bar chart", value=True)

# Filter data
filtered = df[df["Rating"] >= min_rating]
st.dataframe(filtered)

# Chart
if show_chart:
    fig, ax = plt.subplots()
    ax.bar(filtered["Product"], filtered["Sales"], color="#10B981")
    ax.set_ylabel("Sales")
    ax.set_title("Sales by Product")
    plt.xticks(rotation=30)
    plt.tight_layout()
    st.pyplot(fig)
```

<Tip>
  Structure your data apps so that expensive operations (file reading, API calls, database queries) happen inside `@st.cache_data` functions. Everything that depends on widget values belongs in the main script body where it can react to user input.
</Tip>
