|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import matplotlib.pyplot as plt |
|
|
|
|
|
from plot_registry_plt import PlotRegistry |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.set_page_config( |
|
|
page_title="Matplotlib Veri Görselleştirme Aracı", |
|
|
layout="wide" |
|
|
) |
|
|
|
|
|
st.title("📊 Matplotlib Tabanlı Veri Görselleştirme Aracı") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def detect_columns(df: pd.DataFrame): |
|
|
numeric = [] |
|
|
categorical = [] |
|
|
ignore = [] |
|
|
|
|
|
for col in df.columns: |
|
|
nunique = df[col].nunique(dropna=True) |
|
|
ratio = nunique / max(len(df), 1) |
|
|
|
|
|
if pd.api.types.is_numeric_dtype(df[col]): |
|
|
if ratio < 0.05: |
|
|
categorical.append(col) |
|
|
else: |
|
|
numeric.append(col) |
|
|
else: |
|
|
if ratio > 0.7: |
|
|
ignore.append(col) |
|
|
else: |
|
|
categorical.append(col) |
|
|
|
|
|
return numeric, categorical, ignore |
|
|
|
|
|
|
|
|
def eda_summary(df: pd.DataFrame): |
|
|
st.subheader("🔍 Basit EDA Özeti") |
|
|
|
|
|
st.markdown("**Veri Seti**") |
|
|
st.dataframe(df.head()) |
|
|
|
|
|
c1, c2 = st.columns(2) |
|
|
|
|
|
with c1: |
|
|
st.markdown("**Veri Boyutu**") |
|
|
st.write(df.shape) |
|
|
|
|
|
st.markdown("**Eksik Değerler**") |
|
|
st.dataframe(df.isnull().sum().to_frame("Eksik Sayısı")[df.isnull().sum() > 0]) |
|
|
|
|
|
with c2: |
|
|
st.markdown("**Sayısal Alan İstatistikleri**") |
|
|
st.dataframe(df.describe().T) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
registry = PlotRegistry("plots.json") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uploaded = st.file_uploader( |
|
|
"📁 CSV / XLS / XLSX dosyası yükleyin", |
|
|
type=["csv", "xls", "xlsx"] |
|
|
) |
|
|
|
|
|
if not uploaded: |
|
|
st.info("Başlamak için bir veri seti yükleyin.") |
|
|
st.stop() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if uploaded.name.endswith(".csv"): |
|
|
df = pd.read_csv(uploaded) |
|
|
else: |
|
|
df = pd.read_excel(uploaded) |
|
|
|
|
|
st.success("Veri başarıyla yüklendi") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
eda_summary(df) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
numeric_cols, cat_cols, ignore_cols = detect_columns(df) |
|
|
|
|
|
st.subheader("🧩 Alan Türleri (Düzenlenebilir)") |
|
|
|
|
|
c1, c2, c3 = st.columns(3) |
|
|
|
|
|
with c1: |
|
|
num_options = df.columns |
|
|
num_default = [c for c in numeric_cols if c in num_options] |
|
|
|
|
|
numeric_cols = st.multiselect( |
|
|
"🔢 Sayısal Alanlar", |
|
|
options=num_options, |
|
|
default=num_default |
|
|
) |
|
|
|
|
|
|
|
|
with c2: |
|
|
cat_options = df.columns |
|
|
cat_default = [c for c in cat_cols if c in cat_options] |
|
|
|
|
|
cat_cols = st.multiselect( |
|
|
"🏷️ Kategorik Alanlar", |
|
|
options=cat_options, |
|
|
default=cat_default |
|
|
) |
|
|
|
|
|
|
|
|
with c3: |
|
|
ignore_cols = st.multiselect( |
|
|
"🚫 Grafik Dışı Alanlar", |
|
|
options=df.columns, |
|
|
default=ignore_cols |
|
|
) |
|
|
|
|
|
usable_cols = numeric_cols + cat_cols |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.divider() |
|
|
st.subheader("📈 Grafik Seçimi") |
|
|
|
|
|
groups = registry.get_groups() |
|
|
|
|
|
group = st.selectbox("Grafik Grubu", groups) |
|
|
plots = registry.get_plots_in_group(group) |
|
|
|
|
|
plot_key = st.selectbox( |
|
|
"Grafik Türü", |
|
|
list(plots.keys()) |
|
|
) |
|
|
|
|
|
plot_info = registry.get_plot(group, plot_key) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.info(f"**Ne zaman kullanılır?**\n\n{plot_info.get('when_to_use','')}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.subheader("🧮 Grafik Alanları") |
|
|
|
|
|
inputs = plot_info.get("inputs", []) |
|
|
|
|
|
vars_selected = {} |
|
|
|
|
|
for inp in inputs: |
|
|
if inp in ["x", "y"]: |
|
|
vars_selected[inp] = st.selectbox( |
|
|
f"{inp.upper()} alanı", |
|
|
options=usable_cols if inp != "y" else usable_cols |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.subheader("⚙️ Grafik Ayarları") |
|
|
|
|
|
PALETTES = { |
|
|
"Default": plt.rcParams['axes.prop_cycle'].by_key()['color'], |
|
|
"Pastel": ["#AEC6CF", "#FFB347", "#B39EB5", "#77DD77"], |
|
|
"Bold": ["#e41a1c", "#377eb8", "#4daf4a", "#984ea3"], |
|
|
"Grayscale": ["#222222", "#555555", "#888888", "#BBBBBB"] |
|
|
} |
|
|
|
|
|
|
|
|
options = {} |
|
|
opts = list(plot_info.get("options", {}).items()) |
|
|
if opts: |
|
|
cols = st.columns(len(opts)) |
|
|
for i, (opt, default) in enumerate(opts): |
|
|
col = cols[i % len(cols)] |
|
|
if opt == "color": |
|
|
palette_name = col.selectbox("🎨 Palet", PALETTES.keys()) |
|
|
palette = PALETTES[palette_name] |
|
|
options[opt] = col.color_picker("Tek Renk", palette[0]) |
|
|
else: |
|
|
options[opt] = col.text_input(opt, value=str(default) if default is not None else "") |
|
|
else: |
|
|
st.write("Bu grafik tipi için özelleştirilebilir ayar yok.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.subheader("🖼️ Genel Görsel Ayarlar") |
|
|
|
|
|
col1, col2 = st.columns([1, 4]) |
|
|
|
|
|
with col1: |
|
|
fig_w = st.number_input("Figür Genişliği", 4, 20, 8) |
|
|
fig_h = st.number_input("Figür Yüksekliği", 4, 20, 5) |
|
|
|
|
|
with col2: |
|
|
title = st.text_input("Başlık", "Grafik Başlığı") |
|
|
xlabel = st.text_input("X Etiketi", vars_selected.get("x", "")) |
|
|
ylabel = st.text_input("Y Etiketi", vars_selected.get("y", "")) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.divider() |
|
|
st.subheader("📊 Grafik") |
|
|
|
|
|
fig, ax = plt.subplots(figsize=(fig_w, fig_h)) |
|
|
|
|
|
|
|
|
clean_options = options |
|
|
|
|
|
exec_code, display_code = registry.generate_code( |
|
|
group=group, |
|
|
plot_key=plot_key, |
|
|
variables={ |
|
|
"x": f"df['{vars_selected.get('x')}']", |
|
|
"y": f"df['{vars_selected.get('y')}']" |
|
|
}, |
|
|
user_options=options, |
|
|
figsize=(fig_w, fig_h), |
|
|
title=title, |
|
|
xlabel=xlabel, |
|
|
ylabel=ylabel |
|
|
) |
|
|
|
|
|
|
|
|
try: |
|
|
exec(exec_code, {"df": df, "plt": plt, "ax": ax}) |
|
|
except Exception as e: |
|
|
st.error("Grafik oluşturulurken hata oluştu.") |
|
|
st.exception(e) |
|
|
else: |
|
|
st.pyplot(fig) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import io |
|
|
|
|
|
buf = io.BytesIO() |
|
|
fig.savefig(buf, format="png", dpi=300) |
|
|
buf.seek(0) |
|
|
|
|
|
st.download_button( |
|
|
"⬇️ Grafiği PNG olarak indir", |
|
|
data=buf, |
|
|
file_name="grafik.png", |
|
|
mime="image/png" |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.subheader("🐍 Python Kod Çıktısı (Notebook Uyumlu)") |
|
|
st.code(display_code, language="python") |