File size: 3,390 Bytes
4fc79a4
ff768e2
 
4fc79a4
 
29f87f1
8d1334d
218ce96
4fc79a4
 
69a028d
12598b6
4fc79a4
f7d95ea
218ce96
f7d95ea
6cff8d5
218ce96
69a028d
218ce96
 
 
 
 
 
 
 
 
29f87f1
218ce96
 
 
a888f55
f7d95ea
a888f55
218ce96
 
 
 
 
 
 
5fcb5c4
a888f55
6cff8d5
 
218ce96
6cff8d5
 
218ce96
a888f55
 
 
f7d95ea
a888f55
218ce96
 
 
 
 
 
 
 
 
 
 
 
5fcb5c4
218ce96
f7d95ea
a888f55
218ce96
8d1334d
f7d95ea
8d1334d
5fcb5c4
 
a888f55
 
 
5fcb5c4
218ce96
5fcb5c4
a888f55
5fcb5c4
a888f55
6cff8d5
218ce96
 
6cff8d5
 
218ce96
 
6cff8d5
218ce96
 
6cff8d5
 
218ce96
6cff8d5
 
 
 
 
 
 
218ce96
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
import gradio as gr
import pandas as pd
import matplotlib.pyplot as plt
import io
import google.generativeai as genai
from PIL import Image
import ast
import re

def process_file(api_key, file, instructions):
    genai.configure(api_key=api_key)
    model = genai.GenerativeModel('gemini-2.5-pro-preview-03-25')

    try:
        df = pd.read_csv(file.name) if file.name.endswith('.csv') else pd.read_excel(file.name)
    except Exception as e:
        print(f"File Error: {str(e)}")
        return [None]*3

    # Enhanced prompt with strict syntax rules
    prompt = f"""Generate 3 Python code blocks for matplotlib visualizations with:
    1. Perfect Python syntax
    2. No markdown or incomplete lines
    3. Each block must start with:
       plt.figure(figsize=(16,9), dpi=120)
       plt.style.use('ggplot')
    4. Use ONLY df and plt variables
    5. End with plt.tight_layout()
    
    Columns: {list(df.columns)}
    Sample: {df.head(3).to_dict()}
    Instructions: {instructions or 'None'}
    
    Format EXACTLY as:
    # Visualization 1
    [code]
    
    # Visualization 2
    [code]
    
    # Visualization 3
    [code]
    """

    try:
        response = model.generate_content(prompt)
        code_blocks = re.split(r'# Visualization \d+', response.text)[1:4]
    except Exception as e:
        print(f"Gemini Error: {str(e)}")
        return [None]*3

    visualizations = []
    for i, block in enumerate(code_blocks, 1):
        buf = io.BytesIO()
        try:
            # Advanced code cleaning
            cleaned_code = '\n'.join(
                line.strip().replace("'", "").replace('"', '')  # Remove stray quotes
                for line in block.split('\n') 
                if line.strip() and 
                not any(c in line for c in ['`', '```', 'Annotation']) and
                re.match(r'^[a-zA-Z0-9_().=, <>:]+$', line)  # Basic syntax validation
            )
            
            # Add missing parentheses check
            cleaned_code = re.sub(r'plt.style.use\([\'"]ggplot$', 
                                'plt.style.use("ggplot")', cleaned_code)
            
            # Syntax validation
            ast.parse(cleaned_code)
            
            # Execute code
            exec_env = {'df': df, 'plt': plt}
            plt.figure(figsize=(16, 9), dpi=120)
            exec(cleaned_code, exec_env)
            
            plt.savefig(buf, format='png', bbox_inches='tight')
            plt.close()
            visualizations.append(Image.open(buf))
        except Exception as e:
            print(f"Visualization {i} Error: {str(e)}")
            print(f"Cleaned Code:\n{cleaned_code}")
            visualizations.append(None)

    return visualizations + [None]*(3-len(visualizations))

# Gradio interface
with gr.Blocks() as demo:
    gr.Markdown("# Professional Data Visualizer")
    
    with gr.Row():
        api_key = gr.Textbox(label="Gemini API Key", type="password")
        file = gr.File(label="Upload Data File", file_types=[".csv", ".xlsx"])
    
    instructions = gr.Textbox(label="Visualization Instructions")
    submit = gr.Button("Generate", variant="primary")
    
    with gr.Row():
        outputs = [gr.Image(label=f"Visualization {i+1}", width=600) for i in range(3)]

    submit.click(
        process_file,
        inputs=[api_key, file, instructions],
        outputs=outputs
    )

demo.launch()