SHELLAPANDIANGANHUNGING commited on
Commit
c868721
·
verified ·
1 Parent(s): 5dd7d3e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -23
app.py CHANGED
@@ -725,7 +725,7 @@ st.markdown(f"""
725
  # """, unsafe_allow_html=True)
726
  st.markdown("""
727
  <h3 class="objective-title">OBJECTIVE 3: Alarm Frequency Analysis — When, Where, and Which Tyres Matter Most?</h3>
728
- <small>*Showing all alarm types: Normal (Green), Abnormal (Red)</small>
729
  """, unsafe_allow_html=True)
730
 
731
  # Filter semua data (termasuk alarm normal)
@@ -744,7 +744,7 @@ with col_b:
744
  alarm_data['Alarm_Category'] = alarm_data['Alarm Status'].apply(
745
  lambda x: 'Normal' if x == 'No Alarm'
746
  else 'Red Alarm' if x == 'Red High Pressure'
747
- else 'Amber Alarm' # Semua selain No Alarm dan Red High Pressure
748
  )
749
 
750
  # Buat 4 donut chart
@@ -796,9 +796,9 @@ with col_b:
796
  )
797
  st.plotly_chart(fig_donut, use_container_width=True)
798
 
799
- # =============== COL A: Radial Charts (Count Alarm per Jam - 2 Warna: Normal vs Abnormal) ===============
800
  with col_a:
801
- st.markdown('<h5 style="text-align:center; margin-top: 0;">Alarm Count by Hour (Radial)</h5>', unsafe_allow_html=True)
802
 
803
  if alarm_data.empty:
804
  st.warning("No data to display.")
@@ -814,29 +814,53 @@ with col_a:
814
  for i, pos in enumerate([1, 2, 3, 4], 1):
815
  pos_data = alarm_data[alarm_data['Position'] == pos].copy()
816
  if not pos_data.empty:
817
- # Kelompokkan jam
818
- hourly_counts = pos_data.groupby('hour').size().reindex(range(24), fill_value=0)
819
 
820
- # Tentukan apakah jam tersebut "Normal" atau "Abnormal"
821
- # Normal: hanya jika semua alarm di jam tersebut adalah "No Alarm"
822
- # Abnormal: jika ada minimal satu "Amber" atau "Red"
823
- hourly_status = pos_data.groupby('hour')['Alarm Status'].apply(
824
- lambda x: 'Normal' if (x == 'No Alarm').all() else 'Abnormal'
825
- ).reindex(range(24), fill_value='Normal')
826
 
827
- # Warna: Hijau untuk Normal, Merah untuk Abnormal
828
- color_map = {'Normal': '#2E7D32', 'Abnormal': '#D32F2F'}
829
- colorscale = [color_map.get(status, '#2E7D32') for status in hourly_status]
830
 
831
- # Sudut: jam 0 → 0° (atas), jam 6 → 90° (kanan), jam 12 → 180° (bawah), jam 18 → 270° (kiri)
832
- theta = [h * 15 for h in range(24)] # 24 jam * 15° = 360°
833
 
 
834
  fig_radial.add_trace(
835
  go.Barpolar(
836
- r=hourly_counts.values,
837
  theta=theta,
838
- name=f'Position {pos}',
839
- marker_color=colorscale,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
840
  opacity=0.8
841
  ),
842
  row=(i - 1) // 2 + 1,
@@ -851,14 +875,14 @@ with col_a:
851
  angularaxis=dict(
852
  direction="clockwise",
853
  period=24,
854
- rotation=90, # Jam 0 di atas
855
  tickvals=[0, 90, 180, 270],
856
- ticktext=["00:00", "06:00", "12:00", "18:00"],
857
  tickfont=dict(size=12)
858
  ),
859
  radialaxis=dict(
860
  visible=True,
861
- range=[0, max(hourly_counts.max() * 1.1, 1)]
862
  )
863
  )
864
  )
 
725
  # """, unsafe_allow_html=True)
726
  st.markdown("""
727
  <h3 class="objective-title">OBJECTIVE 3: Alarm Frequency Analysis — When, Where, and Which Tyres Matter Most?</h3>
728
+ <small>*Showing all alarm types: Normal (Green), Amber (Yellow), Red (Red)</small>
729
  """, unsafe_allow_html=True)
730
 
731
  # Filter semua data (termasuk alarm normal)
 
744
  alarm_data['Alarm_Category'] = alarm_data['Alarm Status'].apply(
745
  lambda x: 'Normal' if x == 'No Alarm'
746
  else 'Red Alarm' if x == 'Red High Pressure'
747
+ else 'Amber Alarm'
748
  )
749
 
750
  # Buat 4 donut chart
 
796
  )
797
  st.plotly_chart(fig_donut, use_container_width=True)
798
 
799
+ # =============== COL A: Radial Charts (Count Alarm per Jam - Stacked by Status) ===============
800
  with col_a:
801
+ st.markdown('<h5 style="text-align:center; margin-top: 0;">Alarm Count by Hour (Radial - Stacked)</h5>', unsafe_allow_html=True)
802
 
803
  if alarm_data.empty:
804
  st.warning("No data to display.")
 
814
  for i, pos in enumerate([1, 2, 3, 4], 1):
815
  pos_data = alarm_data[alarm_data['Position'] == pos].copy()
816
  if not pos_data.empty:
817
+ # Kelompokkan jam dan status
818
+ hourly_status_counts = pos_data.groupby(['hour', 'Alarm Status']).size().unstack(fill_value=0)
819
 
820
+ # Ambil masing-masing kategori
821
+ hourly_normal = hourly_status_counts.get('No Alarm', pd.Series(0, index=range(24)))
822
+ hourly_amber = hourly_status_counts.get('Amber High Pressure', pd.Series(0, index=range(24))) # Ganti sesuai nama kolom Anda
823
+ hourly_red = hourly_status_counts.get('Red High Pressure', pd.Series(0, index=range(24)))
 
 
824
 
825
+ # Total per jam
826
+ total_per_hour = hourly_normal + hourly_amber + hourly_red
 
827
 
828
+ # Sudut: jam 3 → 0° (atas), jam 12 → 90° (kanan), jam 9 → 180° (bawah), jam 6 → 270° (kiri)
829
+ theta = [(h - 3) * 15 % 360 for h in range(24)] # Jam 3 pagi = 0°
830
 
831
+ # Tambahkan bar polar untuk Normal (hijau)
832
  fig_radial.add_trace(
833
  go.Barpolar(
834
+ r=hourly_normal.values,
835
  theta=theta,
836
+ name='Normal',
837
+ marker_color='#2E7D32', # Hijau
838
+ opacity=0.8
839
+ ),
840
+ row=(i - 1) // 2 + 1,
841
+ col=(i - 1) % 2 + 1
842
+ )
843
+
844
+ # Tambahkan bar polar untuk Amber (kuning) — ditumpuk di atas Normal
845
+ fig_radial.add_trace(
846
+ go.Barpolar(
847
+ r=hourly_amber.values,
848
+ theta=theta,
849
+ name='Amber',
850
+ marker_color='#FFC107', # Kuning
851
+ opacity=0.8
852
+ ),
853
+ row=(i - 1) // 2 + 1,
854
+ col=(i - 1) % 2 + 1
855
+ )
856
+
857
+ # Tambahkan bar polar untuk Red (merah) — ditumpuk di atas Amber
858
+ fig_radial.add_trace(
859
+ go.Barpolar(
860
+ r=hourly_red.values,
861
+ theta=theta,
862
+ name='Red',
863
+ marker_color='#D32F2F', # Merah
864
  opacity=0.8
865
  ),
866
  row=(i - 1) // 2 + 1,
 
875
  angularaxis=dict(
876
  direction="clockwise",
877
  period=24,
878
+ rotation=0, # Jam 3 pagi di atas
879
  tickvals=[0, 90, 180, 270],
880
+ ticktext=["03:00", "12:00", "21:00", "18:00"],
881
  tickfont=dict(size=12)
882
  ),
883
  radialaxis=dict(
884
  visible=True,
885
+ range=[0, max(total_per_hour.max() * 1.1, 1)]
886
  )
887
  )
888
  )