Practice: sales dashboard

Bars, scatter, heatmap, and export from the sample CSVs.

Attach all four sample files (sales.csv, sales_log.csv, products.csv, regions.csv) with Add files. Paste each block as the whole editor — later blocks repeat the load so they still run alone.

Goal

Build four seaborn views of the sales log and export dashboard.png.

1. Load

import os

print("uploads:", os.listdir("/uploads"))
log = pd.read_csv("sales_log.csv", parse_dates=["date"])
log["revenue"] = log["units"] * log["price"]
print(log.head())
print("rows:", len(log), "cities:", log["city"].nunique())

2. Revenue by city

log = pd.read_csv("sales_log.csv")
log["revenue"] = log["units"] * log["price"]
sns.barplot(data=log, x="city", y="revenue", estimator="sum", errorbar=None)
plt.xticks(rotation=30)
plt.title("Total revenue by city")
plt.show()

3. Scatter with product

log = pd.read_csv("sales_log.csv")
log["revenue"] = log["units"] * log["price"]
sns.scatterplot(data=log, x="units", y="revenue", hue="product", style="city")
plt.title("Each sale")
plt.show()

4. Heatmap city × product

log = pd.read_csv("sales_log.csv")
log["revenue"] = log["units"] * log["price"]
table = log.pivot_table(
    index="city", columns="product", values="revenue", aggfunc="sum", fill_value=0
)
print(table)
sns.heatmap(table, annot=True, fmt=".0f", cmap="YlOrBr")
plt.title("Revenue")
plt.show()

5. Region bars via merge

log = pd.read_csv("sales_log.csv")
regions = pd.read_csv("regions.csv")
products = pd.read_csv("products.csv")
log = log.merge(regions, on="city").merge(products, on="product")
log["revenue"] = log["units"] * log["price"]
sns.barplot(
    data=log,
    x="region",
    y="revenue",
    hue="category",
    estimator="sum",
    errorbar=None,
)
plt.title("Region × category")
plt.show()

6. Export a 2×2 figure

import os

log = pd.read_csv("sales_log.csv", parse_dates=["date"])
regions = pd.read_csv("regions.csv")
log = log.merge(regions, on="city")
log["revenue"] = log["units"] * log["price"]
table = log.pivot_table(
    index="city", columns="product", values="revenue", aggfunc="sum", fill_value=0
)

fig, axes = plt.subplots(2, 2, figsize=(9, 7))

sns.barplot(
    data=log,
    x="city",
    y="revenue",
    estimator="sum",
    errorbar=None,
    ax=axes[0, 0],
)
axes[0, 0].tick_params(axis="x", rotation=30)
axes[0, 0].set_title("Revenue by city")

sns.scatterplot(
    data=log,
    x="units",
    y="revenue",
    hue="product",
    ax=axes[0, 1],
    legend=False,
)
axes[0, 1].set_title("Units vs revenue")

sns.heatmap(table, annot=True, fmt=".0f", cmap="YlOrBr", ax=axes[1, 0])
axes[1, 0].set_title("City × product")

sns.countplot(data=log, x="region", hue="product", ax=axes[1, 1])
axes[1, 1].set_title("Rows by region")

fig.suptitle("Kenya kiosk sales")
fig.tight_layout()
fig.savefig("dashboard.png", dpi=120, bbox_inches="tight")
plt.show()
print("uploads:", os.listdir("/uploads"))

Pass ax= so axes-level seaborn functions draw onto your subplot. Click on dashboard.png.

Extra drills

  • Color the city bars by region after the merge.
  • Replace the scatter with sns.boxplot(data=log, x="product", y="revenue", ax=...).
  • Save dashboard.svg as well.
You should see

If a CSV is missing, attach the banner files and run again. Empty Plot panel usually means the script never called plt.show().