SHELLAPANDIANGANHUNGING commited on
Commit
41d61cf
·
verified ·
1 Parent(s): d21a6c7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -18
app.py CHANGED
@@ -1031,6 +1031,7 @@ try:
1031
  from wordcloud import WordCloud
1032
  import matplotlib.pyplot as plt
1033
  import plotly.express as px
 
1034
  WORDCLOUD_AVAILABLE = True
1035
  except ImportError:
1036
  WORDCLOUD_AVAILABLE = False
@@ -1082,36 +1083,33 @@ if WORDCLOUD_AVAILABLE:
1082
  pull_values = []
1083
  for cat in category_counts.index:
1084
  if cat in ['Unsafe Action', 'Near Miss']:
1085
- pull_values.append(0.1) # Tarik keluar sedikit
1086
  else:
1087
  pull_values.append(0.0)
1088
 
1089
  fig_pie.update_traces(
1090
- textposition='outside', # Label di luar slice
1091
- textinfo='percent+label', # Tampilkan persentase + nama
1092
- pull=pull_values, # Tarik slice keluar untuk Unsafe Action & Near Miss
1093
  marker=dict(line=dict(color='#FFFFFF', width=1))
1094
  )
1095
  fig_pie.update_layout(
1096
- showlegend=False, # ❌ matikan legend default
1097
  height=450,
1098
  margin=dict(t=20, b=20, l=40, r=40)
1099
  )
1100
  st.plotly_chart(fig_pie, use_container_width=True)
1101
 
1102
- # ✅ CUSTOM LEGEND: Semua kategori dengan ikon GARIS HORIZONTAL kecil (mirip referensi)
1103
  st.markdown("<div style='text-align: center; font-size: 14px; margin-top: -10px;'>", unsafe_allow_html=True)
1104
  legend_items = []
1105
-
1106
  for cat in category_counts.index:
1107
  color = color_map.get(cat, '#9E9E9E')
1108
  item = (
1109
  f"<span style='display: inline-block; width: 16px; height: 4px; background-color: {color}; "
1110
- f"margin: 0 8px; border-radius: 1px;'></span>"
1111
- f"{cat}"
1112
  )
1113
  legend_items.append(item)
1114
-
1115
  legend_html = " | ".join(legend_items)
1116
  st.markdown(f"<div>{legend_html}</div>", unsafe_allow_html=True)
1117
  st.markdown("</div>", unsafe_allow_html=True)
@@ -1137,15 +1135,16 @@ if WORDCLOUD_AVAILABLE:
1137
  st.warning("No data available after filtering out 'Positive' category.")
1138
  else:
1139
  if 'keyword_kategori' in df_filtered_kategori.columns:
1140
- # Gabungkan text
1141
  import re
1142
- text = ' '.join(df_filtered_kategori['keyword_kategori'].dropna().astype(str))
1143
- text = re.sub(r'[^a-zA-Z\s]', ' ', text)
 
1144
 
1145
- if text.strip():
1146
- # Buat WordCloud
1147
  wordcloud = WordCloud(
1148
- width=1600, # resolusi besar agar HD
1149
  height=800,
1150
  background_color='white',
1151
  colormap='viridis',
@@ -1153,13 +1152,30 @@ if WORDCLOUD_AVAILABLE:
1153
  random_state=42
1154
  ).generate(text)
1155
 
1156
- # Output kecil tapi tajam
1157
  fig, ax = plt.subplots(figsize=(3, 2), dpi=200)
1158
  ax.imshow(wordcloud, interpolation='bilinear')
1159
  ax.axis('off')
1160
  plt.tight_layout()
1161
-
1162
  st.pyplot(fig, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1163
  else:
1164
  st.warning("No valid text remaining after cleaning.")
1165
  else:
 
1031
  from wordcloud import WordCloud
1032
  import matplotlib.pyplot as plt
1033
  import plotly.express as px
1034
+ from collections import Counter
1035
  WORDCLOUD_AVAILABLE = True
1036
  except ImportError:
1037
  WORDCLOUD_AVAILABLE = False
 
1083
  pull_values = []
1084
  for cat in category_counts.index:
1085
  if cat in ['Unsafe Action', 'Near Miss']:
1086
+ pull_values.append(0.1)
1087
  else:
1088
  pull_values.append(0.0)
1089
 
1090
  fig_pie.update_traces(
1091
+ textposition='outside',
1092
+ textinfo='percent+label',
1093
+ pull=pull_values,
1094
  marker=dict(line=dict(color='#FFFFFF', width=1))
1095
  )
1096
  fig_pie.update_layout(
1097
+ showlegend=False,
1098
  height=450,
1099
  margin=dict(t=20, b=20, l=40, r=40)
1100
  )
1101
  st.plotly_chart(fig_pie, use_container_width=True)
1102
 
1103
+ # ✅ CUSTOM LEGEND
1104
  st.markdown("<div style='text-align: center; font-size: 14px; margin-top: -10px;'>", unsafe_allow_html=True)
1105
  legend_items = []
 
1106
  for cat in category_counts.index:
1107
  color = color_map.get(cat, '#9E9E9E')
1108
  item = (
1109
  f"<span style='display: inline-block; width: 16px; height: 4px; background-color: {color}; "
1110
+ f"margin: 0 8px; border-radius: 1px;'></span>{cat}"
 
1111
  )
1112
  legend_items.append(item)
 
1113
  legend_html = " | ".join(legend_items)
1114
  st.markdown(f"<div>{legend_html}</div>", unsafe_allow_html=True)
1115
  st.markdown("</div>", unsafe_allow_html=True)
 
1135
  st.warning("No data available after filtering out 'Positive' category.")
1136
  else:
1137
  if 'keyword_kategori' in df_filtered_kategori.columns:
1138
+ # Gabungkan & bersihkan teks
1139
  import re
1140
+ text_series = df_filtered_kategori['keyword_kategori'].dropna().astype(str)
1141
+ text = ' '.join(text_series)
1142
+ text = re.sub(r'[^a-zA-Z\s]', ' ', text).strip()
1143
 
1144
+ if text:
1145
+ # Generate wordcloud
1146
  wordcloud = WordCloud(
1147
+ width=1600,
1148
  height=800,
1149
  background_color='white',
1150
  colormap='viridis',
 
1152
  random_state=42
1153
  ).generate(text)
1154
 
1155
+ # Tampilkan
1156
  fig, ax = plt.subplots(figsize=(3, 2), dpi=200)
1157
  ax.imshow(wordcloud, interpolation='bilinear')
1158
  ax.axis('off')
1159
  plt.tight_layout()
 
1160
  st.pyplot(fig, use_container_width=True)
1161
+
1162
+ # 🔍 🔹 Insight dinamis: top 3 keywords
1163
+ words_clean = [w.lower() for w in text.split() if len(w) > 2]
1164
+ top3 = [word.capitalize() for word, _ in Counter(words_clean).most_common(3)]
1165
+ if top3:
1166
+ insight = f"The most frequent unsafe issue themes are: <strong>{', '.join(top3)}</strong>."
1167
+ else:
1168
+ insight = "Recurring unsafe issue patterns are detectable in textual findings."
1169
+
1170
+ st.markdown(
1171
+ f"""
1172
+ <div style='text-align: center; font-size: 14px; color: #2c3e50; margin-top: 12px; line-height: 1.5;'>
1173
+ <strong>Insight:</strong> {insight}
1174
+ </div>
1175
+ """,
1176
+ unsafe_allow_html=True
1177
+ )
1178
+
1179
  else:
1180
  st.warning("No valid text remaining after cleaning.")
1181
  else: