abdullatifkaban commited on
Commit
99a0c40
·
verified ·
1 Parent(s): 3b7ada9

Upload 3 files

Browse files
Files changed (3) hide show
  1. app_matplotlib.py +279 -0
  2. plot_registry.py +88 -0
  3. plots.json +178 -0
app_matplotlib.py ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+
6
+ from plot_registry_plt import PlotRegistry
7
+
8
+
9
+ # -------------------------------------------------
10
+ # Sayfa ayarları
11
+ # -------------------------------------------------
12
+ st.set_page_config(
13
+ page_title="Matplotlib Veri Görselleştirme Aracı",
14
+ layout="wide"
15
+ )
16
+
17
+ st.title("📊 Matplotlib Tabanlı Veri Görselleştirme Aracı")
18
+
19
+
20
+ # -------------------------------------------------
21
+ # Yardımcı fonksiyonlar
22
+ # -------------------------------------------------
23
+ def detect_columns(df: pd.DataFrame):
24
+ numeric = []
25
+ categorical = []
26
+ ignore = []
27
+
28
+ for col in df.columns:
29
+ nunique = df[col].nunique(dropna=True)
30
+ ratio = nunique / max(len(df), 1)
31
+
32
+ if pd.api.types.is_numeric_dtype(df[col]):
33
+ if ratio < 0.05:
34
+ categorical.append(col)
35
+ else:
36
+ numeric.append(col)
37
+ else:
38
+ if ratio > 0.7:
39
+ ignore.append(col)
40
+ else:
41
+ categorical.append(col)
42
+
43
+ return numeric, categorical, ignore
44
+
45
+
46
+ def eda_summary(df: pd.DataFrame):
47
+ st.subheader("🔍 Basit EDA Özeti")
48
+
49
+ st.markdown("**Veri Seti**")
50
+ st.dataframe(df.head())
51
+
52
+ c1, c2 = st.columns(2)
53
+
54
+ with c1:
55
+ st.markdown("**Veri Boyutu**")
56
+ st.write(df.shape)
57
+
58
+ st.markdown("**Eksik Değerler**")
59
+ st.dataframe(df.isnull().sum().to_frame("Eksik Sayısı")[df.isnull().sum() > 0])
60
+
61
+ with c2:
62
+ st.markdown("**Sayısal Alan İstatistikleri**")
63
+ st.dataframe(df.describe().T)
64
+
65
+
66
+ # -------------------------------------------------
67
+ # Plot registry
68
+ # -------------------------------------------------
69
+ registry = PlotRegistry("plots.json")
70
+
71
+
72
+ # -------------------------------------------------
73
+ # Dosya yükleme
74
+ # -------------------------------------------------
75
+ uploaded = st.file_uploader(
76
+ "📁 CSV / XLS / XLSX dosyası yükleyin",
77
+ type=["csv", "xls", "xlsx"]
78
+ )
79
+
80
+ if not uploaded:
81
+ st.info("Başlamak için bir veri seti yükleyin.")
82
+ st.stop()
83
+
84
+ # -------------------------------------------------
85
+ # Veri okuma
86
+ # -------------------------------------------------
87
+ if uploaded.name.endswith(".csv"):
88
+ df = pd.read_csv(uploaded)
89
+ else:
90
+ df = pd.read_excel(uploaded)
91
+
92
+ st.success("Veri başarıyla yüklendi")
93
+
94
+ # -------------------------------------------------
95
+ # EDA
96
+ # -------------------------------------------------
97
+ eda_summary(df)
98
+
99
+ # -------------------------------------------------
100
+ # Alan tespiti
101
+ # -------------------------------------------------
102
+
103
+ numeric_cols, cat_cols, ignore_cols = detect_columns(df)
104
+
105
+ st.subheader("🧩 Alan Türleri (Düzenlenebilir)")
106
+
107
+ c1, c2, c3 = st.columns(3)
108
+
109
+ with c1:
110
+ num_options = df.columns
111
+ num_default = [c for c in numeric_cols if c in num_options]
112
+
113
+ numeric_cols = st.multiselect(
114
+ "🔢 Sayısal Alanlar",
115
+ options=num_options,
116
+ default=num_default
117
+ )
118
+
119
+
120
+ with c2:
121
+ cat_options = df.columns
122
+ cat_default = [c for c in cat_cols if c in cat_options]
123
+
124
+ cat_cols = st.multiselect(
125
+ "🏷️ Kategorik Alanlar",
126
+ options=cat_options,
127
+ default=cat_default
128
+ )
129
+
130
+
131
+ with c3:
132
+ ignore_cols = st.multiselect(
133
+ "🚫 Grafik Dışı Alanlar",
134
+ options=df.columns,
135
+ default=ignore_cols
136
+ )
137
+
138
+ usable_cols = numeric_cols + cat_cols
139
+
140
+
141
+ # -------------------------------------------------
142
+ # Grafik seçimi
143
+ # -------------------------------------------------
144
+ st.divider()
145
+ st.subheader("📈 Grafik Seçimi")
146
+
147
+ groups = registry.get_groups()
148
+
149
+ group = st.selectbox("Grafik Grubu", groups)
150
+ plots = registry.get_plots_in_group(group)
151
+
152
+ plot_key = st.selectbox(
153
+ "Grafik Türü",
154
+ list(plots.keys())
155
+ )
156
+
157
+ plot_info = registry.get_plot(group, plot_key)
158
+
159
+ # -------------------------------------------------
160
+ # Açıklama
161
+ # -------------------------------------------------
162
+ st.info(f"**Ne zaman kullanılır?**\n\n{plot_info.get('when_to_use','')}")
163
+
164
+ # -------------------------------------------------
165
+ # Alan seçimi
166
+ # -------------------------------------------------
167
+ st.subheader("🧮 Grafik Alanları")
168
+
169
+ inputs = plot_info.get("inputs", [])
170
+
171
+ vars_selected = {}
172
+
173
+ for inp in inputs:
174
+ if inp in ["x", "y"]:
175
+ vars_selected[inp] = st.selectbox(
176
+ f"{inp.upper()} alanı",
177
+ options=usable_cols if inp != "y" else usable_cols
178
+ )
179
+
180
+ # -------------------------------------------------
181
+ # Grafik özel ayarları
182
+ # -------------------------------------------------
183
+ st.subheader("⚙️ Grafik Ayarları")
184
+
185
+ PALETTES = {
186
+ "Default": plt.rcParams['axes.prop_cycle'].by_key()['color'],
187
+ "Pastel": ["#AEC6CF", "#FFB347", "#B39EB5", "#77DD77"],
188
+ "Bold": ["#e41a1c", "#377eb8", "#4daf4a", "#984ea3"],
189
+ "Grayscale": ["#222222", "#555555", "#888888", "#BBBBBB"]
190
+ }
191
+
192
+
193
+ options = {}
194
+ opts = list(plot_info.get("options", {}).items())
195
+ if opts:
196
+ cols = st.columns(len(opts))
197
+ for i, (opt, default) in enumerate(opts):
198
+ col = cols[i % len(cols)]
199
+ if opt == "color":
200
+ palette_name = col.selectbox("🎨 Palet", PALETTES.keys())
201
+ palette = PALETTES[palette_name]
202
+ options[opt] = col.color_picker("Tek Renk", palette[0])
203
+ else:
204
+ options[opt] = col.text_input(opt, value=str(default) if default is not None else "")
205
+ else:
206
+ st.write("Bu grafik tipi için özelleştirilebilir ayar yok.")
207
+
208
+
209
+ # -------------------------------------------------
210
+ # Genel ayarlar
211
+ # -------------------------------------------------
212
+ st.subheader("🖼️ Genel Görsel Ayarlar")
213
+
214
+ col1, col2 = st.columns([1, 4])
215
+
216
+ with col1:
217
+ fig_w = st.number_input("Figür Genişliği", 4, 20, 8)
218
+ fig_h = st.number_input("Figür Yüksekliği", 4, 20, 5)
219
+
220
+ with col2:
221
+ title = st.text_input("Başlık", "Grafik Başlığı")
222
+ xlabel = st.text_input("X Etiketi", vars_selected.get("x", ""))
223
+ ylabel = st.text_input("Y Etiketi", vars_selected.get("y", ""))
224
+
225
+ # -------------------------------------------------
226
+ # Grafik çizimi
227
+ # -------------------------------------------------
228
+ st.divider()
229
+ st.subheader("📊 Grafik")
230
+
231
+ fig, ax = plt.subplots(figsize=(fig_w, fig_h))
232
+
233
+ # options string -> python obj
234
+ clean_options = options
235
+
236
+ exec_code, display_code = registry.generate_code(
237
+ group=group,
238
+ plot_key=plot_key,
239
+ variables={
240
+ "x": f"df['{vars_selected.get('x')}']",
241
+ "y": f"df['{vars_selected.get('y')}']"
242
+ },
243
+ user_options=options,
244
+ figsize=(fig_w, fig_h),
245
+ title=title,
246
+ xlabel=xlabel,
247
+ ylabel=ylabel
248
+ )
249
+
250
+ # Grafik kodunu çalıştır (try/except)
251
+ try:
252
+ exec(exec_code, {"df": df, "plt": plt, "ax": ax})
253
+ except Exception as e:
254
+ st.error("Grafik oluşturulurken hata oluştu.")
255
+ st.exception(e)
256
+ else:
257
+ st.pyplot(fig)
258
+
259
+ # -------------------------------------------------
260
+ # PNG indirme
261
+ # -------------------------------------------------
262
+ import io
263
+
264
+ buf = io.BytesIO()
265
+ fig.savefig(buf, format="png", dpi=300)
266
+ buf.seek(0)
267
+
268
+ st.download_button(
269
+ "⬇️ Grafiği PNG olarak indir",
270
+ data=buf,
271
+ file_name="grafik.png",
272
+ mime="image/png"
273
+ )
274
+
275
+ # -------------------------------------------------
276
+ # Kod gösterimi
277
+ # -------------------------------------------------
278
+ st.subheader("🐍 Python Kod Çıktısı (Notebook Uyumlu)")
279
+ st.code(display_code, language="python")
plot_registry.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from pathlib import Path
3
+
4
+
5
+ class PlotRegistry:
6
+ def __init__(self, json_path: str):
7
+ self.path = Path(json_path)
8
+ with open(self.path, "r", encoding="utf-8") as f:
9
+ self.registry = json.load(f)
10
+
11
+ # -------------------------------------------------
12
+ # Registry helpers
13
+ # -------------------------------------------------
14
+ def get_groups(self):
15
+ return list(self.registry.keys())
16
+
17
+ def get_plots_in_group(self, group: str):
18
+ return self.registry[group]
19
+
20
+ def get_plot(self, group: str, plot_key: str):
21
+ return self.registry[group][plot_key]
22
+
23
+ # -------------------------------------------------
24
+ # Code generation (FINAL)
25
+ # -------------------------------------------------
26
+ def generate_code(
27
+ self,
28
+ group: str,
29
+ plot_key: str,
30
+ variables: dict,
31
+ user_options: dict,
32
+ figsize=(8, 5),
33
+ title: str = "",
34
+ xlabel: str = "",
35
+ ylabel: str = "",
36
+ ):
37
+ plot = self.get_plot(group, plot_key)
38
+ # Template artık sadece fonksiyon adını içerebilir: "sns.scatterplot"
39
+ # Ancak mevcut JSON yapınızı bozmamak için string manipülasyonu yapacağız.
40
+ base_func = plot["code_template"].split("(")[0]
41
+
42
+ # -----------------------------
43
+ # Dinamik Argüman Oluşturma
44
+ # -----------------------------
45
+ exec_args = ["data=df", "ax=ax"]
46
+ display_args = ["data=df"]
47
+
48
+ # 1. Zorunlu ve Opsiyonel Inputlar (x, y, hue, size vb.)
49
+ for name, value in variables.items():
50
+ if value is not None:
51
+ exec_args.append(f"{name}={name}")
52
+ display_args.append(f"{name}='{value}'")
53
+
54
+ # 2. Opsiyonel Ayarlar (alpha, bins, kde vb.)
55
+ for k, v in user_options.items():
56
+ if v not in ("", None):
57
+ exec_args.append(f"{k}={k}")
58
+ if isinstance(v, str):
59
+ display_args.append(f"{k}={repr(v)}")
60
+ else:
61
+ display_args.append(f"{k}={v}")
62
+
63
+ # -----------------------------
64
+ # Final Kod Oluşturma
65
+ # -----------------------------
66
+ exec_plot_line = f"{base_func}({', '.join(exec_args)})"
67
+ display_plot_line = f"{base_func}({', '.join(display_args)})"
68
+
69
+ exec_code = f"""
70
+ # --- plotting ---
71
+ {exec_plot_line}
72
+ ax.set_title({repr(title)})
73
+ ax.set_xlabel({repr(xlabel)})
74
+ ax.set_ylabel({repr(ylabel)})
75
+ """
76
+ display_code = f"""
77
+ import matplotlib.pyplot as plt
78
+ import seaborn as sns
79
+
80
+ fig, ax = plt.subplots(figsize={figsize})
81
+ {display_plot_line}
82
+ ax.set_title({repr(title)})
83
+ ax.set_xlabel({repr(xlabel)})
84
+ ax.set_ylabel({repr(ylabel)})
85
+ plt.show()
86
+ """.strip()
87
+
88
+ return exec_code.strip(), display_code
plots.json ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "📊 Temel & Dagilim": {
3
+ "scatter": {
4
+ "label": "Scatter Plot",
5
+ "when_to_use": "İki sayısal değişken arasındaki ilişkiyi ve dağılımı incelemek için kullanılır.",
6
+ "inputs": ["x", "y"],
7
+ "options": {
8
+ "color": "tab:blue",
9
+ "size": 40,
10
+ "alpha": 0.7
11
+ },
12
+ "code_template": "ax.scatter({x}, {y}, c={color}, s={size}, alpha={alpha})"
13
+ },
14
+
15
+ "line": {
16
+ "label": "Line Plot",
17
+ "when_to_use": "Zamana veya sıralı bir değişkene bağlı değişimi göstermek için uygundur.",
18
+ "inputs": ["x", "y"],
19
+ "options": {
20
+ "color": "tab:red",
21
+ "linewidth": 2
22
+ },
23
+ "code_template": "ax.plot({x}, {y}, color={color}, linewidth={linewidth})"
24
+ },
25
+
26
+ "bar": {
27
+ "label": "Bar Plot",
28
+ "when_to_use": "Kategorilere göre sayısal değerleri karşılaştırmak için kullanılır.",
29
+ "inputs": ["x", "y"],
30
+ "options": {
31
+ "color": "tab:green"
32
+ },
33
+ "code_template": "ax.bar({x}, {y}, color={color})"
34
+ },
35
+
36
+ "barh": {
37
+ "label": "Horizontal Bar Plot",
38
+ "when_to_use": "Uzun kategori isimlerinde yatay karşılaştırma için tercih edilir.",
39
+ "inputs": ["x", "y"],
40
+ "options": {
41
+ "color": "tab:purple"
42
+ },
43
+ "code_template": "ax.barh({x}, {y}, color={color})"
44
+ },
45
+
46
+ "hist": {
47
+ "label": "Histogram",
48
+ "when_to_use": "Tek bir sayısal değişkenin dağılımını incelemek için kullanılır.",
49
+ "inputs": ["x"],
50
+ "options": {
51
+ "bins": 20,
52
+ "color": "tab:blue",
53
+ "alpha": 0.7
54
+ },
55
+ "code_template": "ax.hist({x}, bins={bins}, color={color}, alpha={alpha})"
56
+ },
57
+
58
+ "box": {
59
+ "label": "Boxplot",
60
+ "when_to_use": "Dağılım, medyan ve aykırı değerleri görmek için kullanılır.",
61
+ "inputs": ["y"],
62
+ "options": {},
63
+ "code_template": "ax.boxplot({y})"
64
+ },
65
+
66
+ "violin": {
67
+ "label": "Violin Plot",
68
+ "when_to_use": "Dağılımın yoğunluk yapısını detaylı görmek için kullanılır.",
69
+ "inputs": ["y"],
70
+ "options": {},
71
+ "code_template": "ax.violinplot({y})"
72
+ },
73
+
74
+ "hexbin": {
75
+ "label": "Hexbin Plot",
76
+ "when_to_use": "Yoğun veri noktalarında scatter yerine tercih edilir.",
77
+ "inputs": ["x", "y"],
78
+ "options": {
79
+ "gridsize": 30,
80
+ "cmap": "Blues"
81
+ },
82
+ "code_template": "ax.hexbin({x}, {y}, gridsize={gridsize}, cmap={cmap})"
83
+ }
84
+ },
85
+
86
+ "📈 Iliski & Yogunluk": {
87
+ "errorbar": {
88
+ "label": "Error Bar",
89
+ "when_to_use": "Ölçüm belirsizliği veya hata payı olan verilerde kullanılır.",
90
+ "inputs": ["x", "y"],
91
+ "options": {
92
+ "yerr": "None"
93
+ },
94
+ "code_template": "ax.errorbar({x}, {y}, yerr={yerr}, fmt='o')"
95
+ },
96
+
97
+ "stem": {
98
+ "label": "Stem Plot",
99
+ "when_to_use": "Ayrık veri noktalarının büyüklüğünü vurgulamak için kullanılır.",
100
+ "inputs": ["x", "y"],
101
+ "options": {},
102
+ "code_template": "ax.stem({x}, {y})"
103
+ },
104
+
105
+ "step": {
106
+ "label": "Step Plot",
107
+ "when_to_use": "Basamaklı değişimleri göstermek için uygundur.",
108
+ "inputs": ["x", "y"],
109
+ "options": {},
110
+ "code_template": "ax.step({x}, {y})"
111
+ },
112
+
113
+ "fill_between": {
114
+ "label": "Fill Between",
115
+ "when_to_use": "İki eğri veya sıfır ile alan doldurmak için kullanılır.",
116
+ "inputs": ["x", "y"],
117
+ "options": {
118
+ "alpha": 0.4
119
+ },
120
+ "code_template": "ax.fill_between({x}, {y}, alpha={alpha})"
121
+ }
122
+ },
123
+
124
+ "🧭 Zaman Serisi & Istatistik": {
125
+ "rolling_mean": {
126
+ "label": "Rolling Mean",
127
+ "when_to_use": "Zaman serilerinde trendi yumuşatarak görmek için kullanılır.",
128
+ "inputs": ["y"],
129
+ "options": {
130
+ "window": 5
131
+ },
132
+ "code_template": "ax.plot({y}.rolling(window={window}).mean())"
133
+ },
134
+
135
+ "lag_plot": {
136
+ "label": "Lag Plot",
137
+ "when_to_use": "Zaman serilerinde otokorelasyonu görsel olarak incelemek için kullanılır.",
138
+ "inputs": ["y"],
139
+ "options": {
140
+ "lag": 1
141
+ },
142
+ "code_template": "ax.scatter({y}.shift({lag})[ {lag}: ], {y}[ {lag}: ])"
143
+ }
144
+ },
145
+
146
+ "🎯 Kategorik & Ozel": {
147
+ "pie": {
148
+ "label": "Pie Chart",
149
+ "when_to_use": "Bir bütünün parçalara oranını göstermek için kullanılır.",
150
+ "inputs": ["y"],
151
+ "options": {
152
+ "startangle": 90,
153
+ "autopct": "%1.2f%%"
154
+ },
155
+ "code_template": "ss={y}.value_counts(); ax.pie(ss, labels=ss.index, autopct={autopct})"
156
+ },
157
+
158
+ "donut": {
159
+ "label": "Donut Chart",
160
+ "when_to_use": "Pie chart'ın daha modern ve okunabilir hâlidir.",
161
+ "inputs": ["x", "y"],
162
+ "options": {},
163
+ "code_template": "wedges, _ = ax.pie({y}, labels={x}); centre = plt.Circle((0,0),0.6,fc='white'); ax.add_artist(centre)"
164
+ }
165
+ },
166
+
167
+ "🧠 Korelasyon": {
168
+ "correlation_heatmap": {
169
+ "label": "Correlation Heatmap",
170
+ "when_to_use": "Sayısal değişkenler arasındaki korelasyon ilişkilerini görmek için kullanılır.",
171
+ "inputs": [],
172
+ "options": {
173
+ "cmap": "coolwarm"
174
+ },
175
+ "code_template": "corr = df.select_dtypes(include='number').corr(); im = ax.imshow(corr, cmap={cmap}); ax.set_xticks(range(len(corr.columns))); ax.set_yticks(range(len(corr.columns))); ax.set_xticklabels(corr.columns, rotation=90); ax.set_yticklabels(corr.columns); plt.colorbar(im, ax=ax)"
176
+ }
177
+ }
178
+ }