entropy25 commited on
Commit
ec43aa0
·
verified ·
1 Parent(s): c185c85

Create visualization.py

Browse files
Files changed (1) hide show
  1. visualization.py +197 -0
visualization.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import plotly.graph_objects as go
2
+ import plotly.express as px
3
+ from plotly.subplots import make_subplots
4
+ import numpy as np
5
+ from collections import Counter
6
+ from typing import List, Dict, Optional
7
+
8
+ from models import handle_errors, ThemeContext
9
+
10
+ # Optimized Plotly Visualization System
11
+ class PlotlyVisualizer:
12
+ """Enhanced Plotly visualizations"""
13
+
14
+ @staticmethod
15
+ @handle_errors(default_return=None)
16
+ def create_sentiment_gauge(result: Dict, theme: ThemeContext) -> go.Figure:
17
+ """Create animated sentiment gauge"""
18
+ colors = theme.colors
19
+
20
+ if result.get('has_neutral', False):
21
+ # Three-way gauge
22
+ fig = go.Figure(go.Indicator(
23
+ mode="gauge+number+delta",
24
+ value=result['pos_prob'] * 100,
25
+ domain={'x': [0, 1], 'y': [0, 1]},
26
+ title={'text': f"Sentiment: {result['sentiment']}"},
27
+ delta={'reference': 50},
28
+ gauge={
29
+ 'axis': {'range': [None, 100]},
30
+ 'bar': {'color': colors['pos'] if result['sentiment'] == 'Positive' else colors['neg']},
31
+ 'steps': [
32
+ {'range': [0, 33], 'color': colors['neg']},
33
+ {'range': [33, 67], 'color': colors['neu']},
34
+ {'range': [67, 100], 'color': colors['pos']}
35
+ ],
36
+ 'threshold': {
37
+ 'line': {'color': "red", 'width': 4},
38
+ 'thickness': 0.75,
39
+ 'value': 90
40
+ }
41
+ }
42
+ ))
43
+ else:
44
+ # Two-way gauge
45
+ fig = go.Figure(go.Indicator(
46
+ mode="gauge+number",
47
+ value=result['confidence'] * 100,
48
+ domain={'x': [0, 1], 'y': [0, 1]},
49
+ title={'text': f"Confidence: {result['sentiment']}"},
50
+ gauge={
51
+ 'axis': {'range': [None, 100]},
52
+ 'bar': {'color': colors['pos'] if result['sentiment'] == 'Positive' else colors['neg']},
53
+ 'steps': [
54
+ {'range': [0, 50], 'color': "lightgray"},
55
+ {'range': [50, 100], 'color': "gray"}
56
+ ]
57
+ }
58
+ ))
59
+
60
+ fig.update_layout(height=400, font={'size': 16})
61
+ return fig
62
+
63
+ @staticmethod
64
+ @handle_errors(default_return=None)
65
+ def create_probability_bars(result: Dict, theme: ThemeContext) -> go.Figure:
66
+ """Create probability bar chart"""
67
+ colors = theme.colors
68
+
69
+ if result.get('has_neutral', False):
70
+ labels = ['Negative', 'Neutral', 'Positive']
71
+ values = [result['neg_prob'], result['neu_prob'], result['pos_prob']]
72
+ bar_colors = [colors['neg'], colors['neu'], colors['pos']]
73
+ else:
74
+ labels = ['Negative', 'Positive']
75
+ values = [result['neg_prob'], result['pos_prob']]
76
+ bar_colors = [colors['neg'], colors['pos']]
77
+
78
+ fig = go.Figure(data=[
79
+ go.Bar(x=labels, y=values, marker_color=bar_colors,
80
+ text=[f'{v:.3f}' for v in values], textposition='outside')
81
+ ])
82
+
83
+ fig.update_layout(
84
+ title="Sentiment Probabilities",
85
+ yaxis_title="Probability",
86
+ height=400,
87
+ showlegend=False
88
+ )
89
+ return fig
90
+
91
+ @staticmethod
92
+ @handle_errors(default_return=None)
93
+ def create_batch_summary(results: List[Dict], theme: ThemeContext) -> go.Figure:
94
+ """Create batch analysis summary"""
95
+ colors = theme.colors
96
+
97
+ # Count sentiments
98
+ sentiments = [r['sentiment'] for r in results if 'sentiment' in r and r['sentiment'] != 'Error']
99
+ sentiment_counts = Counter(sentiments)
100
+
101
+ # Create pie chart
102
+ fig = go.Figure(data=[go.Pie(
103
+ labels=list(sentiment_counts.keys()),
104
+ values=list(sentiment_counts.values()),
105
+ marker_colors=[colors.get(s.lower()[:3], '#999999') for s in sentiment_counts.keys()],
106
+ textinfo='label+percent',
107
+ hole=0.3
108
+ )])
109
+
110
+ fig.update_layout(
111
+ title=f"Batch Analysis Summary ({len(results)} texts)",
112
+ height=400
113
+ )
114
+ return fig
115
+
116
+ @staticmethod
117
+ @handle_errors(default_return=None)
118
+ def create_confidence_distribution(results: List[Dict]) -> go.Figure:
119
+ """Create confidence distribution plot"""
120
+ confidences = [r['confidence'] for r in results if 'confidence' in r and r['sentiment'] != 'Error']
121
+ if not confidences:
122
+ return go.Figure()
123
+
124
+ fig = go.Figure(data=[go.Histogram(
125
+ x=confidences,
126
+ nbinsx=20,
127
+ marker_color='skyblue',
128
+ opacity=0.7
129
+ )])
130
+
131
+ fig.update_layout(
132
+ title="Confidence Distribution",
133
+ xaxis_title="Confidence Score",
134
+ yaxis_title="Frequency",
135
+ height=400
136
+ )
137
+ return fig
138
+
139
+ @staticmethod
140
+ @handle_errors(default_return=None)
141
+ def create_history_dashboard(history: List[Dict], theme: ThemeContext) -> go.Figure:
142
+ """Create comprehensive history dashboard"""
143
+ if len(history) < 2:
144
+ return go.Figure()
145
+
146
+ # Create subplots
147
+ fig = make_subplots(
148
+ rows=2, cols=2,
149
+ subplot_titles=['Sentiment Timeline', 'Confidence Distribution',
150
+ 'Language Distribution', 'Sentiment Summary'],
151
+ specs=[[{"secondary_y": False}, {"secondary_y": False}],
152
+ [{"type": "pie"}, {"type": "bar"}]]
153
+ )
154
+
155
+ # Extract data
156
+ indices = list(range(len(history)))
157
+ pos_probs = [item.get('pos_prob', 0) for item in history]
158
+ confidences = [item['confidence'] for item in history]
159
+ sentiments = [item['sentiment'] for item in history]
160
+ languages = [item.get('language', 'en') for item in history]
161
+
162
+ # Sentiment timeline
163
+ colors_map = {'Positive': theme.colors['pos'], 'Negative': theme.colors['neg'], 'Neutral': theme.colors['neu']}
164
+ colors = [colors_map.get(s, '#999999') for s in sentiments]
165
+
166
+ fig.add_trace(
167
+ go.Scatter(x=indices, y=pos_probs, mode='lines+markers',
168
+ marker=dict(color=colors, size=8),
169
+ name='Positive Probability'),
170
+ row=1, col=1
171
+ )
172
+
173
+ # Confidence distribution
174
+ fig.add_trace(
175
+ go.Histogram(x=confidences, nbinsx=10, name='Confidence'),
176
+ row=1, col=2
177
+ )
178
+
179
+ # Language distribution
180
+ lang_counts = Counter(languages)
181
+ fig.add_trace(
182
+ go.Pie(labels=list(lang_counts.keys()), values=list(lang_counts.values()),
183
+ name="Languages"),
184
+ row=2, col=1
185
+ )
186
+
187
+ # Sentiment summary
188
+ sent_counts = Counter(sentiments)
189
+ sent_colors = [colors_map.get(k, '#999999') for k in sent_counts.keys()]
190
+ fig.add_trace(
191
+ go.Bar(x=list(sent_counts.keys()), y=list(sent_counts.values()),
192
+ marker_color=sent_colors),
193
+ row=2, col=2
194
+ )
195
+
196
+ fig.update_layout(height=800, showlegend=False)
197
+ return fig