import streamlit as st import pandas as pd import numpy as np import matplotlib.pyplot as plt from plot_registry_plt import PlotRegistry # ------------------------------------------------- # Sayfa ayarları # ------------------------------------------------- st.set_page_config( page_title="Matplotlib Veri Görselleştirme Aracı", layout="wide" ) st.title("📊 Matplotlib Tabanlı Veri Görselleştirme Aracı") # ------------------------------------------------- # Yardımcı fonksiyonlar # ------------------------------------------------- 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) # ------------------------------------------------- # Plot registry # ------------------------------------------------- registry = PlotRegistry("plots.json") # ------------------------------------------------- # Dosya yükleme # ------------------------------------------------- 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() # ------------------------------------------------- # Veri okuma # ------------------------------------------------- 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 # ------------------------------------------------- eda_summary(df) # ------------------------------------------------- # Alan tespiti # ------------------------------------------------- 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 # ------------------------------------------------- # Grafik seçimi # ------------------------------------------------- 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) # ------------------------------------------------- # Açıklama # ------------------------------------------------- st.info(f"**Ne zaman kullanılır?**\n\n{plot_info.get('when_to_use','')}") # ------------------------------------------------- # Alan seçimi # ------------------------------------------------- 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 ) # ------------------------------------------------- # Grafik özel ayarları # ------------------------------------------------- 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.") # ------------------------------------------------- # Genel ayarlar # ------------------------------------------------- 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", "")) # ------------------------------------------------- # Grafik çizimi # ------------------------------------------------- st.divider() st.subheader("📊 Grafik") fig, ax = plt.subplots(figsize=(fig_w, fig_h)) # options string -> python obj 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 ) # Grafik kodunu çalıştır (try/except) 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) # ------------------------------------------------- # PNG indirme # ------------------------------------------------- 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" ) # ------------------------------------------------- # Kod gösterimi # ------------------------------------------------- st.subheader("🐍 Python Kod Çıktısı (Notebook Uyumlu)") st.code(display_code, language="python")