File size: 3,598 Bytes
c6379ae
9be415c
e760057
 
c6379ae
e760057
 
 
 
 
 
 
 
b13bccc
e760057
b13bccc
 
 
f305b38
e760057
b13bccc
e760057
 
 
 
602a264
e760057
 
 
b13bccc
e760057
 
 
 
 
 
 
 
 
b13bccc
e760057
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f305b38
da71915
e760057
ee16303
 
e760057
 
 
ee16303
da71915
e760057
 
 
 
9239ab3
b13bccc
e760057
b13bccc
e760057
9239ab3
e760057
 
 
 
 
b13bccc
e760057
 
 
 
 
b13bccc
e760057
b13bccc
e760057
 
 
9239ab3
f305b38
b13bccc
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import gradio as gr
import pandas as pd
import plotly.express as px
from sklearn.datasets import make_blobs

def create_dataset():
    # Örnek veri oluştur
    data, _ = make_blobs(n_samples=300, centers=3, n_features=2, random_state=42)
    df = pd.DataFrame(data, columns=['X', 'Y'])
    df['Category'] = ['A', 'B', 'C'] * 100
    return df

def update_columns(csv_file):
    if csv_file is None:
        return [gr.Dropdown(choices=[])] * 2
    df = pd.read_csv(csv_file.name)
    numeric_cols = df.select_dtypes(include=['number']).columns.tolist()
    return gr.Dropdown(choices=numeric_cols), gr.Dropdown(choices=numeric_cols)

def create_plot(csv_file, x_col, y_col):
    if csv_file is None or x_col is None or y_col is None:
        df = create_dataset()
        x_col, y_col = 'X', 'Y'
    else:
        df = pd.read_csv(csv_file.name)
    
    fig = px.scatter(
        df, 
        x=x_col, 
        y=y_col,
        color='Category' if 'Category' in df.columns else None,
        title="Interactive Scatter Plot with Polygon Selection",
        hover_data=df.columns.tolist()
    )
    
    fig.update_layout(
        dragmode='drawclosedpath',  # Polygon çizim modu
        newshape=dict(line_color='cyan'),  # Çizim rengi
        margin=dict(l=20, r=20, b=20, t=40)
    )
    
    config = {
        'modeBarButtonsToAdd': [
            'drawclosedpath',
            'eraseshape'
        ]
    }
    return fig, df

def get_selected_points(plot_data, df):
    if plot_data is None or 'range' in plot_data:
        return pd.DataFrame()
    
    selected_points = []
    for shape in plot_data.get('shapes', []):
        if shape['type'] == 'path':
            x_path = shape['path'].split('L')
            polygon_points = [tuple(map(float, point.split(','))) for point in x_path]
            
            # Polygon içinde kalan noktaları bul
            for idx, row in df.iterrows():
                if is_point_in_polygon((row['X'], row['Y']), polygon_points):
                    selected_points.append(idx)
    
    return df.iloc[selected_points] if selected_points else pd.DataFrame()

def is_point_in_polygon(point, polygon):
    # Ray casting algoritması ile nokta-polygon çakışma kontrolü
    x, y = point
    inside = False
    n = len(polygon)
    
    for i in range(n):
        j = (i + 1) % n
        xi, yi = polygon[i]
        xj, yj = polygon[j]
        
        intersect = ((yi > y) != (yj > y)) and (x < (xj - xi) * (y - yi) / (yj - yi) + xi)
        if intersect:
            inside = not inside
            
    return inside

with gr.Blocks() as app:
    gr.Markdown("## 🔷 Polygon ile Veri Seçimi")
    
    with gr.Row():
        csv_upload = gr.UploadButton(label="CSV Yükle", file_types=[".csv"])
        x_dropdown = gr.Dropdown(label="X Ekseni")
        y_dropdown = gr.Dropdown(label="Y Ekseni")
    
    with gr.Row():
        plot = gr.Plot(label="Scatter Plot")
        selected_table = gr.DataFrame(label="Seçilen Veriler")
    
    df_state = gr.State()
    
    csv_upload.upload(
        fn=update_columns,
        inputs=csv_upload,
        outputs=[x_dropdown, y_dropdown]
    )
    
    x_dropdown.change(
        fn=create_plot,
        inputs=[csv_upload, x_dropdown, y_dropdown],
        outputs=[plot, df_state]
    )
    
    y_dropdown.change(
        fn=create_plot,
        inputs=[csv_upload, x_dropdown, y_dropdown],
        outputs=[plot, df_state]
    )
    
    plot.select(
        fn=get_selected_points,
        inputs=df_state,
        outputs=selected_table
    )

if __name__ == "__main__":
    app.launch()