Аналіз даних та візуалізація за допомогою Python: Pandas + Plotly + Streamlit

Автор Tuvze, Груд. 12, 2025, 06:56 PM

« попередня та - наступна тема »

Tuvze

У 2025 році в Туреччині ніхто більше не створює зведені таблиці в Excel. Pandas + Plotly стали стандартом.

У цьому посібнику ми попрактикуємося з реальними даними про продажі (дані про електронну комерцію в Туреччині за 2020–2025 роки):
  • Очищення та аналіз даних за допомогою Pandas 2.2
  • Інтерактивні графіки за допомогою Plotly
  • Створення живого дашборду за 5 хвилин за допомогою Streamlit
  • Безкоштовне розгортання на Railway / Streamlit Cloud
  • Сумісність з мобільними пристроями + темний режим

1. Встановлення (найактуальніші пакети 2025 року)

python -m venv veri-dashboard
cd veri-dashboard
Scripts\activate
pip install pandas==2.2.2 plotly==5.22 streamlit==1.38 openpyxl python-dotenv

2. Приклад даних (satislar_2025.xlsx)
Приклад таблиці Excel:

[th]Дата[/th]
[th]Продукт[/th]
[th]Категорія[/th]
[th]Кількість[/th]
[th]Ціна[/th]
[th]Місто[/th]
[th]Оплата[/th]
2025-01-15iPhone 16Електроніка245000СтамбулКредит
2025-01-16СветрОдяг5850АнкараГотівка
.....................

3. Аналіз даних – analysis.py
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
import locale

# Встановлення локалі для Туреччини 2025
locale.setlocale(locale.LC_TIME, 'tr_TR.UTF-8')

# Завантаження даних
df = pd.read_excel("satislar_2025.xlsx", parse_dates=["Tarih"])

# Очищення
df["Toplam"] = df["Adet"] * df["Fiyat"]
df["Ay"] = df["Tarih"].dt.strftime("%Y-%m")
df["Gün"] = df["Tarih"].dt.day_name(locale='tr_TR')

print("Загальний дохід:", f"₺{df['Toplam'].sum():,}")
print("Найпопулярніша категорія:", df.groupby("Kategori")["Adet"].sum().idxmax())

4. Інтерактивний дашборд – app.py (Streamlit)
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from pathlib import Path

st.set_page_config(page_title="Дашборд продажів 2025", layout="wide", page_icon="📊")

# Темний режим
st.markdown("""
<style>
.css-1d391kg {padding-top: 1rem; padding-bottom: 3rem;}
.css-18e3th9 {padding-top: 1rem;}
</style>
""", unsafe_allow_html=True)

@st.cache_data
def load_data():
    df = pd.read_excel("satislar_2025.xlsx", parse_dates=["Tarih"])
    df["Toplam"] = df["Adet"] * df["Fiyat"]
    df["Ay"] = df["Tarih"].dt.strftime("%Y-%m")
    df["Ay Adı"] = df["Tarih"].dt.strftime("%B %Y")
    return df

df = load_data()

st.title("Дашборд продажів електронної комерції в Туреччині - 2025")
st.markdown("---")

# KPI
col1, col2, col3, col4 = st.columns(4)
total_revenue = df["Toplam"].sum()
total_orders = len(df)
avg_basket = total_revenue / total_orders if total_orders > 0 else 0
top_city = df["Şehir"].value_counts().index[0]

col1.metric("Загальний оборот", f"₺{total_revenue:,.0f}")
col2.metric("Загальна кількість замовлень", f"{total_orders:,}")
col3.metric("Середній чек", f"₺{avg_basket:,.0f}")
col4.metric("Найпопулярніше місто", top_city)

st.markdown("---")

# Тренд продажів за місяцями
col1, col2 = st.columns(2)
with col1:
    monthly = df.groupby("Ay")["Toplam"].sum().reset_index()
    template = "plotly_dark" if st.checkbox("Темний режим", True) else "plotly"
    fig = px.line(monthly, x="Ay", y="Toplam", title="Тренд обороту за місяцями", markers=True, template=template)
    fig.update_yaxes(title="Оборот (TL)", tickprefix="₺")
    st.plotly_chart(fig, use_container_width=True)

with col2:
    category = df.groupby("Kategori")["Toplam"].sum().reset_index()
    fig2 = px.pie(category, values="Toplam", names="Kategori", title="Розподіл продажів за категоріями")
    st.plotly_chart(fig2, use_container_width=True)

# Продажі за містами
st.subheader("Продажі за містами")
city_sales = df.groupby("Şehir")["Toplam"].sum().reset_index()
fig3 = px.bar(city_sales.sort_values("Toplam", ascending=False).head(10), x="Şehir", y="Toplam", title="Топ-10 міст за продажами")
st.plotly_chart(fig3, use_container_width=True)

# Таблиця + фільтри
st.subheader("Детальна таблиця продажів")
kategori_sec = st.multiselect("Оберіть категорію", df["Kategori"].unique(), default=df["Kategori"].unique())
sehir_sec = st.multiselect("Оберіть місто", df["Şehir"].unique(), default=df["Şehir"].unique())
filtered = df[df["Kategori"].isin(kategori_sec) & df["Şehir"].isin(sehir_sec)]
st.dataframe(filtered, use_container_width=True)

# Експорт в Excel
csv = filtered.to_csv(index=False).encode('utf-8')
st.download_button("Завантажити Excel", csv, "satislar_filtreli.csv", "text/csv")

5. Запуск


streamlit run app.py
# http://localhost:8501


6. Безкоштовне розгортання (2 варіанти)
Варіант 1: Streamlit Cloud (30 секунд)

git init
git add .
git commit -m "first"
# streamlit.io → New app → Підключіть репозиторій GitHub → Deploy
# https://satis-dashboard-2025.streamlit.app


Варіант 2: Railway.app

railway login
railway init
railway up
# Автоматичне розгортання

7. Продуктивність (2025)

[th]Інструмент[/th]
[th]Час розгортання[/th]
[th]Сумісність з мобільними[/th]
[th]Інтерактивність[/th]
[th]Вартість[/th]
Power BI10+ хвилинСередняСередня$10/міс
Tableau15+ хвилинГарнаГарна$70/міс
Streamlit + Plotly30 секундВідміннаВідміннаБезкоштовно

Висновок
Цей дашборд пропонує:
  • Фільтрацію в реальному часі
  • Сумісність з мобільними та десктопними пристроями
  • Експорт в Excel
  • Темний режим
  • Живий за 5 хвилин
  • Готовий для презентації керівництву!

Повний вихідний код (працюючий):
https://github.com/kullanicin/veri-dashboard-2025

Жива демонстрація:
https://satis-dashboard-2025.streamlit.app