CoolFace
Apppublic

53Devon/Dota_2_Machine_Learning

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
visualization.py1250 linesDownload Raw Back to root
1# Library dokumentasi streamlit
2import streamlit as st
3
4# Library pengolahan data
5import pandas as pd
6import json
7
8# Library visualisasi
9import plotly.express as px
10
11
12def run():
13    df = pd.read_csv("P1M2_Devon.csv")
14    df["DURATION"] = df["DURATION"].apply(
15        lambda x: int(x.split(":")[0]) * 60 + int(x.split(":")[1])
16    )
17    df["SCORE"] = pd.to_numeric(df["SCORE"], errors="coerce")
18    df["SCORE"] = df["SCORE"].astype("Int64")
19
20    with open("team.txt", "r") as file:
21        team = json.load(file)
22
23    with open("tournament.txt", "r") as file:
24        tournament = json.load(file)
25
26    with open("heroes.txt", "r") as file:
27        heroes = json.load(file)
28
29    st.subheader("🧩Exploratory Data Analysis")
30    st.write(
31        "Visualisasi data dilakukan untuk mengidentifikasi pola, anomali dan memberikan wawasan terkait informasi umum dari Dataframe."
32    )
33    st.write("")
34
35    expander_1 = st.expander(
36        "#### 🎯 Grafik Visualisasi Skor dan Durasi", expanded=True
37    )
38    with expander_1:
39        st.write("")
40
41        col_1, col_divier, col_2 = st.columns((68, 0.00000000001, 100))
42
43        col_1.markdown(
44            "<div style='margin-left: 18px'>Grafik ini menunjukkan informasi mengenai skor yang diperoleh dan durasi pertandingan 🕒</div>",
45            unsafe_allow_html=True,
46        )
47
48        with col_divier:
49            st.markdown(
50                '<div style="height: 80px; border-right: 1px solid grey;"></div>',
51                unsafe_allow_html=True,
52            )
53
54        col_2.markdown(
55            '<div style="margin-left: 25px; margin-bottom: 10px">Berikut merupakan <i>filter</i> yang dapat digunakan.',
56            unsafe_allow_html=True,
57        )
58        col_20, col_21, col_22, col_23, col_24 = col_2.columns(
59            (0.01, 10.7, 15.8, 13, 3)
60        )
61        st.write("")
62
63        exclude_team_popover = None
64        input_team_popover = None
65        exclude_tournament_popover = None
66        input_tournament_popover = None
67        exclude_karakter_popover = None
68        input_karakter_popover = None
69
70        with col_21.popover("Team"):
71            filter_mode = st.toggle("Mode Exclude Team")
72            if not filter_mode:
73                input_team_popover = st.multiselect(
74                    "Nama Tim yang ingin di-include",
75                    sorted(team),
76                    help="Field ini memungkinkan pengguna untuk mengisi nama tim yang ingin dipilih",
77                )
78            if filter_mode:
79                exclude_team_popover = st.multiselect(
80                    "Nama Tim yang ingin di-exclude",
81                    sorted(team),
82                    help="Field ini memungkinkan pengguna untuk mengisi nama tim yang tidak ingin dipilih.",
83                )
84
85        if not input_team_popover:
86            input_team_popover = "No Filter"
87        if not exclude_team_popover:
88            exclude_team_popover = "No Filter"
89
90        with col_22.popover("Tournament"):
91            filter_mode_2 = st.toggle("Mode Exclude Tournament")
92            if not filter_mode_2:
93                input_tournament_popover = st.multiselect(
94                    "Nama Tournament yang ingin di-include",
95                    sorted(tournament),
96                    help="Field ini memungkinkan pengguna untuk mengisi nama tournament yang ingin dipilih",
97                )
98            if filter_mode_2:
99                exclude_tournament_popover = st.multiselect(
100                    "Nama Tournament yang ingin di-exclude",
101                    sorted(tournament),
102                    help="Field ini memungkinkan pengguna untuk mengisi nama tournament yang tidak ingin dipilih.",
103                )
104        if not input_tournament_popover:
105            input_tournament_popover = "No Filter"
106        if not exclude_tournament_popover:
107            exclude_tournament_popover = "No Filter"
108
109        with col_23.popover("Karakter"):
110            filter_mode_2 = st.toggle("Mode Exclude karakter")
111            if not filter_mode_2:
112                input_karakter_popover = st.multiselect(
113                    "Nama karakter yang ingin di-include",
114                    sorted(heroes),
115                    help="Field ini memungkinkan pengguna untuk mengisi nama karakter yang ingin dipilih",
116                )
117            if filter_mode_2:
118                exclude_karakter_popover = st.multiselect(
119                    "Nama karakter yang ingin di-exclude",
120                    sorted(heroes),
121                    help="Field ini memungkinkan pengguna untuk mengisi nama karakter yang tidak ingin dipilih.",
122                )
123        if not input_karakter_popover:
124            input_karakter_popover = "No Filter"
125        if not exclude_karakter_popover:
126            exclude_karakter_popover = "No Filter"
127
128        df_hist = df
129        title = "          Histogram Distribusi Skor Pertandingan Keseluruhan Tim"
130        insight = "Mayoritas skor dalam pertandingan selama 2019 - 2022 berakhir diantara skor 10 sampai 40 sementara cukup sedikit data skor di atas 50 dan di bawah 5."
131
132        if input_team_popover != "No Filter":
133            df_hist = df_hist[df_hist["TEAM"].isin(input_team_popover)]
134            title = f'          Histogram Distribusi Skor Pertandingan {", ".join(input_team_popover)}'
135
136        if exclude_team_popover != "No Filter":
137            df_hist = df_hist[~df_hist["TEAM"].isin(exclude_team_popover)]
138            title = f'          Histogram Distribusi Skor Pertandingan Tidak Termasuk {", ".join(exclude_team_popover)}'
139
140        if input_tournament_popover != "No Filter":
141            df_hist = df_hist[df_hist["TOURNAMENT"].isin(input_tournament_popover)]
142
143        if exclude_tournament_popover != "No Filter":
144            df_hist = df_hist[~df_hist["TOURNAMENT"].isin(exclude_tournament_popover)]
145
146        if input_karakter_popover != "No Filter":
147            df_hist = df_hist[
148                df_hist[["HERO_1", "HERO_2", "HERO_3", "HERO_4", "HERO_5"]]
149                .isin(input_karakter_popover)
150                .any(axis=1)
151            ]
152
153        if exclude_karakter_popover != "No Filter":
154            df_hist = df_hist[
155                ~df_hist[["HERO_1", "HERO_2", "HERO_3", "HERO_4", "HERO_5"]]
156                .isin(exclude_karakter_popover)
157                .any(axis=1)
158            ]
159
160        tab_0, tab_a, tab_b, tab_c = st.tabs(
161            [
162                " ",
163                "Skor Keseluruhan",
164                "Skor Berdasarkan Hasil",
165                "Durasi Keseluruhan",
166            ]
167        )
168        with tab_0:
169            st.write("")
170            st.markdown(
171                '<div style="margin-left: 28px">Terdapat tiga tab yang dapat diakses, yaitu:</div>',
172                unsafe_allow_html=True,
173            )
174            st.write("")
175            st.markdown(
176                "1. **Skor Keseluruhan**:a Tab ini akan menampilkan ringkasan semua skor pertandingan yang ada dalam dataset. \n\n2. **Skor Berdasarkan Hasil**:a Tab ini akan menampilkan perbandingan skor antara hasil pertandingan menang dan kalah.\n3. **Durasi Keseluruhan**:a Tab ini akan menyajikan data mengenai durasi rata-rata atau total dari semua pertandingan."
177            )
178
179        with tab_a:
180            fig = px.histogram(
181                df_hist,
182                x="SCORE",
183                nbins=50,
184                barmode="overlay",
185                color_discrete_sequence=["#58a3cd", "#9baebc"],
186            )
187
188            fig.update_layout(
189                title=title,
190                xaxis_title="Skor Pertandingan",
191                yaxis_title="Jumlah",
192                barmode="overlay",
193                margin=dict(r=80),
194            )
195
196            fig.add_annotation(
197                x=df_hist["SCORE"].mean(),
198                y=0.9,
199                text="Average <br>Line",
200                xref="x",
201                yref="paper",
202                showarrow=True,
203                arrowhead=4,
204                arrowsize=1,
205                arrowwidth=2,
206                arrowcolor="#9baebc",
207                ax=0,
208                ay=-35,
209                font=dict(color="#58a3cd"),
210            )
211
212            fig.add_shape(
213                type="line",
214                x1=df_hist["SCORE"].mean(),
215                x0=df_hist["SCORE"].mean(),
216                y0=0,
217                y1=0.89,
218                xref="x",
219                yref="paper",
220                line=dict(color="#9baebc", dash="dash", width=1.5),
221                name="Average WIN",
222            )
223            st.plotly_chart(fig)
224
225            col0, col1, col3, col4, col5, col6 = st.columns((3, 10, 10, 10, 10, 5))
226
227            if (
228                (input_team_popover == "No Filter")
229                and (exclude_team_popover == "No Filter")
230                and (exclude_tournament_popover == "No Filter")
231                and (input_tournament_popover == "No Filter")
232                and (input_karakter_popover == "No Filter")
233                and (exclude_karakter_popover == "No Filter")
234            ):
235                col1.metric("Rata-rata Skor", f'{df_hist["SCORE"].mean():.2f}')
236                col3.metric("Modus Skor", f'{df_hist["SCORE"].mode()[0]}')
237                col4.metric("Skor Minimum", f'{df_hist["SCORE"].min()}')
238                col5.metric("Skor Maximum", f'{df_hist["SCORE"].max()}')
239
240            else:
241                col1.metric(
242                    "Rata-rata Skor",
243                    f'{df_hist["SCORE"].mean():.2f}',
244                    (f'{(df_hist["SCORE"].mean())-(df["SCORE"].mean()):.2f}'),
245                )
246                col3.metric(
247                    "Modus Skor",
248                    f'{df_hist["SCORE"].mode()[0]}',
249                    (f'{(df_hist["SCORE"].mode()[0])-(df["SCORE"].mode()[0]):.2f}'),
250                )
251                col4.metric(
252                    "Skor Minimum",
253                    f'{df_hist["SCORE"].min()}',
254                    (f'{(df_hist["SCORE"].min())-(df["SCORE"].min()):.2f}'),
255                )
256                col5.metric(
257                    "Skor Maximum",
258                    f'{df_hist["SCORE"].max()}',
259                    (f'{(df_hist["SCORE"].max())-(df["SCORE"].max()):.2f}'),
260                )
261
262            st.write("")
263            st.markdown(
264                f'<div style="margin-left: 40px; margin-right: 60px;text-align: justify; ">{insight}</div>',
265                unsafe_allow_html=True,
266            )
267            col_div, col, col_div2 = st.columns((1, 18, 1))
268            t1 = col.toggle("Detail Informasi DataFrame")
269            if t1:
270                col.dataframe(df_hist)
271
272        with tab_b:
273            fig = px.histogram(
274                df_hist,
275                x="SCORE",
276                barmode="overlay",
277                color="RESULT",
278                color_discrete_map={"LOSE": "lightcoral", "WIN": "lightskyblue"},
279            )
280
281            fig.update_layout(
282                title=title,
283                xaxis_title="Skor Pertandingan",
284                yaxis_title="Jumlah",
285                barmode="overlay",
286            )
287
288            fig.add_annotation(
289                x=df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mean(),
290                y=0.9,
291                text="Average <br>Win ",
292                xref="x",
293                yref="paper",
294                showarrow=True,
295                arrowhead=4,
296                arrowcolor="#9baebc",
297                ax=0,
298                ay=-35,
299                font=dict(color="#58a3cd"),
300            )
301
302            fig.add_shape(
303                type="line",
304                x1=df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mean(),
305                x0=df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mean(),
306                y0=0,
307                y1=0.89,
308                xref="x",
309                yref="paper",
310                line=dict(color="#9baebc", dash="dash", width=1.5),
311                name="Average WIN",
312            )
313
314            fig.add_annotation(
315                x=df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mean(),
316                y=0.9,
317                text="Average<br>Lose",
318                xref="x",
319                yref="paper",
320                showarrow=True,
321                arrowhead=4,
322                arrowcolor="#9baebc",
323                ax=0,
324                ay=-35,
325                font=dict(color="#c85d5f"),
326            )
327
328            fig.add_shape(
329                type="line",
330                x1=df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mean(),
331                x0=df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mean(),
332                y0=0,
333                y1=0.89,
334                xref="x",
335                yref="paper",
336                line=dict(color="#9baebc", dash="dash", width=1.5),
337                name="Average Lose",
338            )
339            st.plotly_chart(fig)
340
341            col0, col1, col2, col3, col4, col5 = st.columns((3, 10, 10, 10, 10, 5))
342            if (
343                (input_team_popover == "No Filter")
344                and (exclude_team_popover == "No Filter")
345                and (exclude_tournament_popover == "No Filter")
346                and (input_tournament_popover == "No Filter")
347                and (input_karakter_popover == "No Filter")
348                and (exclude_karakter_popover == "No Filter")
349            ):
350                col1.metric(
351                    "Mean Menang",
352                    f'{df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mean():.2f}',
353                )
354                col2.metric(
355                    "Mean Kalah",
356                    f'{df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mean():.2f}',
357                )
358                col3.metric(
359                    "Modus Menang",
360                    f'{df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mode()[0]}',
361                )
362                col4.metric(
363                    "Modus Kalah",
364                    f'{df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mode()[0]}',
365                )
366            else:
367                col1.metric(
368                    "Mean Menang",
369                    f'{df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mean():.2f}',
370                    f'{(df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mean() - (df[df["RESULT"] == "WIN"]["SCORE"].mean())):,.2f}',
371                )
372                col2.metric(
373                    "Mean Kalah",
374                    f'{df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mean():.2f}',
375                    f'{(df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mean() - (df[df["RESULT"] == "LOSE"]["SCORE"].mean())):,.2f}',
376                )
377                col3.metric(
378                    "Modus Menang",
379                    f'{df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mode()[0]}',
380                    f'{(df_hist[df_hist["RESULT"] == "WIN"]["SCORE"].mode()[0]) - (df[df["RESULT"] == "WIN"]["SCORE"].mode()[0]):,.2f}',
381                )
382                col4.metric(
383                    "Modus Kalah",
384                    f'{df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mode()[0]}',
385                    f'{(df_hist[df_hist["RESULT"] == "LOSE"]["SCORE"].mode()[0]) - (df[df["RESULT"] == "LOSE"]["SCORE"].mode()[0]):,.2f}',
386                )
387
388            st.write(
389                '<div style="margin-left: 40px; margin-right: 60px;text-align: justify; ">Terlihat adanya pergeseran mayoritas data hasil pertandingan kalah memiliki skor yang relatif lebih rendah daripada data skor dengan hasil pertandingan menang. Hal ini dianggap wajar dan logis karena tim yang berada pada situasi menang berpotensi memiliki skor yang lebih tinggi dari pada tim lawan.</div>',
390                unsafe_allow_html=True,
391            )
392            col_div, col, col_div2 = st.columns((1, 18, 1))
393            t2 = col.toggle("Detail Informasi DataFrame", key="t2")
394            if t2:
395                col.dataframe(df_hist)
396
397        with tab_c:
398            fig = px.histogram(
399                df_hist,
400                x="DURATION",
401                barmode="overlay",
402            )
403
404            fig.update_layout(
405                title=title,
406                xaxis_title="Durasi Pertandingan (detik)",
407                yaxis_title="Jumlah",
408                barmode="overlay",
409                xaxis_title_standoff=25,
410            )
411
412            fig.add_annotation(
413                x=df_hist["DURATION"].mean(),
414                y=0.9,
415                text="Average <br>duration",
416                xref="x",
417                yref="paper",
418                showarrow=True,
419                arrowhead=4,
420                arrowsize=1,
421                arrowwidth=2,
422                arrowcolor="#9baebc",
423                ax=0,
424                ay=-35,
425                font=dict(color="#58a3cd"),
426            )
427
428            fig.add_shape(
429                type="line",
430                x1=df_hist["DURATION"].mean(),
431                x0=df_hist["DURATION"].mean(),
432                y0=0,
433                y1=0.89,
434                xref="x",
435                yref="paper",
436                line=dict(color="#9baebc", dash="dash", width=1.5),
437                name="Average WIN",
438            )
439
440            st.plotly_chart(fig)
441
442            col0, col1, col3, col4, col5 = st.columns((3, 10, 10, 10, 20))
443
444            if (
445                (input_team_popover == "No Filter")
446                and (exclude_team_popover == "No Filter")
447                and (exclude_tournament_popover == "No Filter")
448                and (input_tournament_popover == "No Filter")
449                and (input_karakter_popover == "No Filter")
450                and (exclude_karakter_popover == "No Filter")
451            ):
452                col1.metric(
453                    "Rata-rata Durasi", f"{(df_hist['DURATION'].mean()/60):.1f}'"
454                )
455                col3.metric(
456                    "Durasi Minimum",
457                    f'{df_hist["DURATION"].min()//60:02d}:{df_hist["DURATION"].min()%60:02d}',
458                )
459                col4.metric(
460                    "Durasi Maximum",
461                    f'{df_hist["DURATION"].max()//60:02d}:{df_hist["DURATION"].max()%60:02d}',
462                )
463
464            else:
465                col1.metric(
466                    "Rata-rata Durasi",
467                    f"{(df_hist['DURATION'].mean()/60):.1f}'",
468                    (
469                        f"{(((df_hist['DURATION'].mean())-(df['DURATION'].mean()))/60):.1f}'"
470                    ),
471                )
472                col3.metric(
473                    "Durasi Minimum",
474                    f'{df_hist["DURATION"].min()//60:02d}:{df_hist["DURATION"].min()%60:02d}',
475                    f'{(df_hist["DURATION"].min()-df["DURATION"].min())//60:02d}:{(df_hist["DURATION"].min()-df["DURATION"].min())%60:02d}',
476                )
477                col4.metric(
478                    "Durasi Maximum",
479                    f'{df_hist["DURATION"].max()//60:02d}:{df_hist["DURATION"].max()%60:02d}',
480                    f'{(df_hist["DURATION"].max()-df["DURATION"].max())//60:02d}:{(df_hist["DURATION"].max()-df["DURATION"].max())%60:02d}',
481                )
482
483            st.write("")
484            st.markdown(
485                '<div style="margin-left: 40px; margin-right: 60px;text-align: justify; ">Mayoritas pertandingan berlangsung diantara 1500 sampai 2500 detik atau setara dengan 25 sampai 41 menit sementara cukup sedikit data pertandingan selesai di bawah 1000 detik dan di atas 4000 detik. ',
486                unsafe_allow_html=True,
487            )
488            col_div, col, col_div2 = st.columns((1, 18, 1))
489
490            if col.toggle("Detail Informasi DataFrame", key="t3"):
491                col.dataframe(df_hist)
492        st.markdown("<br>", unsafe_allow_html=True)
493
494    expander_2 = st.expander("#### 🏆 Grafik Persentase Kemenangan Tim", expanded=True)
495    with expander_2:
496        st.write("")
497        col_1, col_divier, col_2 = st.columns((75, 3, 100))
498
499        col_1.markdown(
500            "<div style='margin-left: 18px'>Grafik ini menampilkan persentase kemenangan tim 🎉, maka dapat dengan mudah melihat performa tim.</div>",
501            unsafe_allow_html=True,
502        )
503
504        with col_divier:
505            st.markdown(
506                '<div style="height: 80px; border-right: 1px solid grey;"></div>',
507                unsafe_allow_html=True,
508            )
509
510        col_2.markdown(
511            '<div style="margin-left: 25px; margin-bottom: 10px">Berikut merupakan <i>filter</i> yang dapat digunakan.',
512            unsafe_allow_html=True,
513        )
514
515        st.write("")
516
517        exclude_tournament_popover = None
518        input_tournament_popover = None
519        exclude_karakter_popover = None
520        input_karakter_popover = None
521
522        col_20, col_22, col_23, col_24 = col_2.columns((2, 18, 16, 11))
523
524        with col_22.popover("Tournament"):
525            filter_mode_3 = st.toggle("Mode Exclude Tournament.")
526            if not filter_mode_3:
527                input_tournament_popover = st.multiselect(
528                    "Nama Tournament yang ingin di-include",
529                    sorted(tournament),
530                    help="Field ini memungkinkan pengguna untuk mengisi nama tournament yang ingin dipilih untuk di-filter",
531                )
532            if filter_mode_3:
533                exclude_tournament_popover = st.multiselect(
534                    "Nama Tournament yang ingin di-exclude",
535                    sorted(tournament),
536                    help="Field ini memungkinkan pengguna untuk mengisi nama tournament yang tidak ingin dipilih untuk di-filter.",
537                )
538        if not input_tournament_popover:
539            input_tournament_popover = "No Filter"
540        if not exclude_tournament_popover:
541            exclude_tournament_popover = "No Filter"
542
543        with col_23.popover("Karakter"):
544            filter_mode_2 = st.toggle("Mode Exclude karakter.")
545            if not filter_mode_2:
546                input_karakter_popover = st.multiselect(
547                    "Nama karakter yang ingin di-include",
548                    sorted(heroes),
549                    help="Field ini memungkinkan pengguna untuk mengisi nama karakter yang ingin dipilih untuk di-filter",
550                )
551            if filter_mode_2:
552                exclude_karakter_popover = st.multiselect(
553                    "Nama karakter yang ingin di-exclude",
554                    sorted(heroes),
555                    help="Field ini memungkinkan pengguna untuk mengisi nama karakter yang tidak ingin dipilih untuk di-filter.",
556                )
557        if not input_karakter_popover:
558            input_karakter_popover = "No Filter"
559        if not exclude_karakter_popover:
560            exclude_karakter_popover = "No Filter"
561
562        df_winrate = df
563        df_unfilter = (
564            (df.groupby("TEAM")["RESULT"].value_counts(normalize=True) * 100)
565            .reset_index()
566            .sort_values(by="proportion", ascending=False)
567        )
568        df_unfilter.rename({"proportion": "Winrate"}, axis=1, inplace=True)
569        df_unfilter = df_unfilter[df_unfilter["RESULT"] == "WIN"]
570
571        if input_tournament_popover != "No Filter":
572            df_winrate = df_winrate[
573                df_winrate["TOURNAMENT"].isin(input_tournament_popover)
574            ]
575
576        if exclude_tournament_popover != "No Filter":
577            df_winrate = df_winrate[
578                ~df_winrate["TOURNAMENT"].isin(exclude_tournament_popover)
579            ]
580
581        if input_karakter_popover != "No Filter":
582            df_winrate = df_winrate[
583                df_winrate[["HERO_1", "HERO_2", "HERO_3", "HERO_4", "HERO_5"]]
584                .isin(input_karakter_popover)
585                .any(axis=1)
586            ]
587
588        if exclude_karakter_popover != "No Filter":
589            df_winrate = df_winrate[
590                ~df_winrate[["HERO_1", "HERO_2", "HERO_3", "HERO_4", "HERO_5"]]
591                .isin(exclude_karakter_popover)
592                .any(axis=1)
593            ]
594
595        tab_00, tab0, tab1 = st.tabs(
596            [
597                " ",
598                "Keseluruhan Winrate",
599                "Perbandingan dengan Jumlah Pertandingan",
600            ]
601        )
602        with tab_00:
603            st.write("")
604            st.markdown(
605                '<div style="margin-left: 28px">Terdapat dua tab yang dapat diakses, yaitu:</div>',
606                unsafe_allow_html=True,
607            )
608            st.write("")
609            st.markdown(
610                "1. **Keseluruhan Winrate**:a Tab ini akan menampilkan ringkasan tingkat kemenangan dari keseluruhan tim. \n\n2. **Perbandingan dengan Jumlah Pertandingan**:a Tab ini akan menampilkan perbandingan tingkat kemenangan dan jumlah pertandingan."
611            )
612        with tab0:
613            df_winrate_final = (
614                (
615                    df_winrate.groupby("TEAM")["RESULT"].value_counts(normalize=True)
616                    * 100
617                )
618                .reset_index()
619                .sort_values(by="proportion", ascending=False)
620            )
621            df_win1 = df_winrate_final[df_winrate_final["RESULT"] == "WIN"]
622            df_win1.rename({"proportion": "Winrate"}, axis=1, inplace=True)
623            df_win1["Match"] = df_win1["TEAM"].apply(
624                lambda team: df_winrate[df_winrate["TEAM"] == team]["TEAM"].count()
625            )
626            df_win1.sort_values(by=["Winrate", "Match"], ascending=False, inplace=True)
627
628            fig3_1 = px.bar(
629                df_win1,
630                x="Winrate",
631                y="TEAM",
632                orientation="h",
633                color="Winrate",
634                color_continuous_scale="rdbu",
635            )
636            fig3_1.update_layout(
637                title="                                        Winrate Keseluruhan Tim",
638                xaxis_title="Persentase Menang (%)",
639            )
640            fig3_1.update_coloraxes(colorbar_title="Winrate(%)")
641
642            if (
643                (input_tournament_popover == "No Filter")
644                and (exclude_tournament_popover == "No Filter")
645                and (input_karakter_popover == "No Filter")
646                and (exclude_karakter_popover == "No Filter")
647            ):
648                fig3_1.add_shape(
649                    type="rect",
650                    x0=0,
651                    x1=46,
652                    y0=173,
653                    y1=67,
654                    line=dict(color="red", width=1.5, dash="dot"),
655                    opacity=0.8,
656                )
657                fig3_1.add_annotation(
658                    x=46,
659                    y=173,
660                    text="<b>Low Winrate</b>",
661                    font_size=18,
662                    font_color="lightcoral",
663                    hovertext="",
664                    showarrow=False,
665                    yshift=-15,
666                    xshift=-60,
667                )
668                fig3_1.add_annotation(
669                    x=46,
670                    y=173,
671                    text="<b>under 45%</b>",
672                    font_size=15,
673                    font_color="lightcoral",
674                    hovertext="",
675                    showarrow=False,
676                    yshift=-33,
677                    xshift=-47,
678                )
679                fig3_1.add_annotation(
680                    x=46,
681                    y=173,
682                    text=f"<b>{df_win1[df_win1['Winrate'] < 45]['TEAM'].count()} teams</b>",
683                    font_size=13,
684                    font_color="lightcoral",
685                    hovertext="",
686                    showarrow=False,
687                    yshift=-50,
688                    xshift=-42,
689                )
690
691                fig3_1.add_shape(
692                    type="rect",
693                    x0=0,
694                    x1=73,
695                    y0=0,
696                    y1=20,
697                    line=dict(color="blue", width=1.5, dash="dot"),
698                    opacity=0.8,
699                )
700                fig3_1.add_annotation(
701                    x=70,
702                    y=20,
703                    text="<b>High Winrate</b>",
704                    font_size=18,
705                    font_color="lightskyblue",
706                    hovertext="",
707                    showarrow=False,
708                    yshift=48,
709                    xshift=-35,
710                )
711                fig3_1.add_annotation(
712                    x=70,
713                    y=20,
714                    text="<b>Over 55%</b>",
715                    font_size=15,
716                    font_color="lightskyblue",
717                    hovertext="",
718                    showarrow=False,
719                    yshift=28,
720                    xshift=-17,
721                )
722                fig3_1.add_annotation(
723                    x=70,
724                    y=20,
725                    text=f"<b>{df_win1[df_win1['Winrate'] > 55]['TEAM'].count()} teams</b>",
726                    font_size=13,
727                    font_color="lightskyblue",
728                    hovertext="",
729                    showarrow=False,
730                    yshift=13,
731                    xshift=-12,
732                )
733
734            fig3_1.update_xaxes(showgrid=True, gridwidth=1, linewidth=2)
735            st.plotly_chart(fig3_1)
736            col0, col1, col3 = st.columns((1, 10, 1))
737
738            if (input_karakter_popover == "No Filter") and (
739                exclude_karakter_popover == "No Filter"
740            ):
741                con1 = col1.container(border=True)
742                con1.markdown(
743                    '<div style="margin-left: 80px; "><h3>Statistik Winrate tim terbaik.',
744                    unsafe_allow_html=True,
745                )
746                col_10, col_11, col_12, col_13, col_00 = con1.columns((1, 12, 5, 5, 1))
747                col_11.metric(
748                    "Tim dengan Winrate tertinggi pertama:",
749                    f"{df_win1['TEAM'].iloc[0]}",
750                )
751                col_12.metric(
752                    "Jumlah Match",
753                    df_win1["Match"].iloc[0],
754                )
755                col_13.metric(
756                    "Winrate (%)",
757                    f'{df_win1["Winrate"].max():.1f}%',
758                )
759                col_11.metric(
760                    "Tim dengan Winrate tertinggi kedua:", f"{df_win1['TEAM'].iloc[1]}"
761                )
762                col_12.metric(
763                    "Jumlah Match",
764                    df_win1["Match"].iloc[1],
765                )
766                col_13.metric(
767                    "Winrate (%)",
768                    f'{df_win1["Winrate"].iloc[1]:.1f}%',
769                )
770                col_11.metric(
771                    "Tim dengan Winrate tertinggi ketiga:", f"{df_win1['TEAM'].iloc[2]}"
772                )
773                col_12.metric(
774                    "Jumlah Match",
775                    df_win1["Match"].iloc[2],
776                )
777                col_13.metric(
778                    "Winrate (%)",
779                    f'{df_win1["Winrate"].iloc[2]:.1f}%',
780                )
781                con1.write("")
782
783            st.write("")
784
785        with tab1:
786            df_winrate_final = (
787                (
788                    df_winrate.groupby("TEAM")["RESULT"].value_counts(normalize=True)
789                    * 100
790                )
791                .reset_index()
792                .sort_values(by="proportion", ascending=False)
793            )
794            df_win1 = df_winrate_final[df_winrate_final["RESULT"] == "WIN"]
795            df_win1.rename({"proportion": "Winrate"}, axis=1, inplace=True)
796            df_win1["label"] = df_win1.apply(
797                lambda row: row["TEAM"] if row["Winrate"] > 63 else "", axis=1
798            )
799            for team in df_win1["TEAM"]:
800                df_win1.loc[df_win1["TEAM"] == team, "match"] = df[df["TEAM"] == team][
801                    "TEAM"
802                ].count()
803
804            fig3 = px.scatter(
805                df_win1,
806                x="match",
807                y="Winrate",
808                hover_name="TEAM",
809                color="match",
810                color_continuous_scale="haline",
811            )
812
813            fig3.update_layout(
814                title="                 Penyebaran Persentase Kemenangan berdasarkan Jumlah Pertandingan",
815                xaxis_title="Jumlah pertandingan",
816                yaxis_title="Persentase Menang (%)",
817            )
818            fig3.update_traces(
819                textposition="top center",
820            )
821            if (
822                (input_tournament_popover == "No Filter")
823                and (exclude_tournament_popover == "No Filter")
824                and (input_karakter_popover == "No Filter")
825                and (exclude_karakter_popover == "No Filter")
826            ):
827                fig3.add_shape(
828                    type="circle",
829                    x0=-120,
830                    x1=200,
831                    y0=0,
832                    y1=80,
833                    line_width=0,
834                    fillcolor="#8897ff",
835                    opacity=0.1,
836                )
837                fig3.add_shape(
838                    type="circle",
839                    x0=215,
840                    x1=820,
841                    y0=78,
842                    y1=33,
843                    line_width=0,
844                    fillcolor="#abffd2",
845                    opacity=0.1,
846                )
847                fig3.add_annotation(
848                    x=46,
849                    y=80,
850                    text="<b>Less Experience<br>Teams</b>",
851                    font_size=20,
852                    font_color="lightskyblue",
853                    hovertext="",
854                    showarrow=False,
855                )
856                fig3.add_annotation(
857                    x=520,
858                    y=77,
859                    text="<b>More Experience Teams</b>",
860                    font_size=20,
861                    font_color="#51b27c",
862                    hovertext="",
863                    showarrow=False,
864                )
865                fig3.add_annotation(
866                    x=520,
867                    y=40,
868                    text="<b>More experience tends to <br>have good winrate</b>",
869                    font_size=15,
870                    font_color="#238a57",
871                    hovertext="",
872                    showarrow=False,
873                )
874
875            fig3.update_xaxes(showgrid=False, gridwidth=1, linewidth=2)
876            st.plotly_chart(fig3)
877
878            col0, col1, col2, col3, col_end = st.columns((3.5, 20, 20, 15, 2))
879
880            if (
881                (exclude_tournament_popover == "No Filter")
882                and (input_tournament_popover == "No Filter")
883                and (input_karakter_popover == "No Filter")
884                and (exclude_karakter_popover == "No Filter")
885            ):
886                col1.metric(
887                    "Persentase Tim Berpengalaman",
888                    f'{df_win1[df_win1["match"] > 200]["TEAM"].count()/df_win1["TEAM"].count()*100:.1f}%',
889                )
890                col2.metric(
891                    "Rata-rata jumlah pertandingan",
892                    f'{(df_win1["match"].mean()):.2f}',
893                )
894                col3.metric(
895                    "Jumlah Tim",
896                    f'{(df_win1["TEAM"].count())}',
897                )
898
899            else:
900                col1.metric(
901                    "Persentase Tim Berpengalaman",
902                    f'{df_win1[df_win1["match"] > 200]["TEAM"].count()/df_win1["TEAM"].count()*100:.1f}%',
903                    f'{(df_win1[df_win1["match"] > 200]["TEAM"].count()/df_win1["TEAM"].count()*100) - (15.1):.1f}%',
904                )
905                col2.metric(
906                    "Rata-rata jumlah pertandingan",
907                    f'{(df_win1["match"].mean()):.2f}',
908                    f'{(df_win1["match"].mean()) - (102.83):.2f}',
909                )
910                col3.metric(
911                    "Jumlah Tim",
912                    f'{(df_win1["TEAM"].count())}',
913                )
914
915            st.markdown(
916                '<div style="margin-left: 40px; margin-right: 60px; text-align: justify; ">Grafik menunjukkan hubungan positif antara jumlah pertandingan dengan persentase kemenangan, dimana tim dengan lebih banyak pertandingan cenderung memiliki persentase kemenangan yang lebih tinggi. Namun, terdapat variasi dalam setiap kelompok, yang mengindikasikan faktor lain selain pengalaman juga mempengaruhi hasil pertandingan.</div>',
917                unsafe_allow_html=True,
918            )
919
920        st.markdown("<br>", unsafe_allow_html=True)
921
922    expander_3 = st.expander("#### 💪 Grafik Popularitas Karakter", expanded=True)
923    with expander_3:
924        st.write("")
925
926        col_1, col_divier, col_2 = st.columns((68, 0.00000000001, 100))
927
928        col_1.write(
929            "<div style='margin-left: 18px'>Grafik ini menunjukkan karakter mana yang paling populer dalam permainan 🕹️ </div>",
930            unsafe_allow_html=True,
931        )
932
933        with col_divier:
934            st.markdown(
935                '<div style="height: 80px; border-right: 1px solid grey;"></div>',
936                unsafe_allow_html=True,
937            )
938
939        col_2.markdown(
940            '<div style="margin-left: 25px; margin-bottom: 10px">Berikut merupakan <i>filter</i> yang dapat digunakan.',
941            unsafe_allow_html=True,
942        )
943
944        col_20, col_21, col_22, col_23 = col_2.columns((2, 10.7, 15.8, 15))
945        st.write("")
946
947        exclude_team_popover = None
948        input_team_popover = None
949        exclude_tournament_popover = None
950        input_tournament_popover = None
951        exclude_karakter_popover = None
952        input_karakter_popover = None
953
954        with open("team.txt", "r") as file:
955            team = json.load(file)
956
957        with col_21.popover("Team"):
958            filter_mode = st.toggle("Mode Exclude Team", key="t5")
959            if not filter_mode:
960                input_team_popover = st.multiselect(
961                    "Nama Tim yang ingin di-include",
962                    sorted(team),
963                    help="Field ini memungkinkan pengguna untuk mengisi nama tim yang ingin dipilih",
964                    key="ms10",
965                )
966            if filter_mode:
967                exclude_team_popover = st.multiselect(
968                    "Nama Tim yang ingin di-exclude",
969                    sorted(team),
970                    help="Field ini memungkinkan pengguna untuk mengisi nama tim yang tidak ingin dipilih.",
971                    key="ms11",
972                )
973        if not input_team_popover:
974            input_team_popover = "No Filter"
975        if not exclude_team_popover:
976            exclude_team_popover = "No Filter"
977
978        with col_22.popover("Tournament"):
979            filter_mode_2 = st.toggle("Mode Exclude Tournament", key="t6")
980            if not filter_mode_2:
981                input_tournament_popover = st.multiselect(
982                    "Nama Tournament yang ingin di-include",
983                    sorted(tournament),
984                    help="Field ini memungkinkan pengguna untuk mengisi nama tournament yang ingin dipilih",
985                    key="ms1",
986                )
987            if filter_mode_2:
988                exclude_tournament_popover = st.multiselect(
989                    "Nama Tournament yang ingin di-exclude",
990                    sorted(tournament),
991                    help="Field ini memungkinkan pengguna untuk mengisi nama tournament yang tidak ingin dipilih.",
992                    key="ms2",
993                )
994        if not input_tournament_popover:
995            input_tournament_popover = "No Filter"
996        if not exclude_tournament_popover:
997            exclude_tournament_popover = "No Filter"
998
999        if input_team_popover != "No Filter":
1000            df_hist = df_hist[df_hist["TEAM"].isin(input_team_popover)]
1001
1002        if exclude_team_popover != "No Filter":
1003            df_hist = df_hist[~df_hist["TEAM"].isin(exclude_team_popover)]
1004
1005        if input_tournament_popover != "No Filter":
1006            df_hist = df_hist[df_hist["TOURNAMENT"].isin(input_tournament_popover)]
1007
1008        if exclude_tournament_popover != "No Filter":
1009            df_hist = df_hist[~df_hist["TOURNAMENT"].isin(exclude_tournament_popover)]
1010
1011        tab_0, tab1, tab2 = st.tabs(
1012            [
1013                " ",
1014                "Popularitas Keseluruhan",
1015                "Popularitas berdasarkan Jumlah Penggunaan",
1016            ]
1017        )
1018
1019        df_bar_1 = (
1020            df_hist[["HERO_1", "HERO_2", "HERO_3", "HERO_4", "HERO_5"]]
1021            .stack()
1022            .value_counts()
1023            .reset_index()
1024        )
1025        df_bar_1.columns = ["HERO", "COUNT"]
1026        df_bar_1["WIN COUNT"] = 0
1027        for index, row in df_bar_1.iterrows():
1028            hero = row["HERO"]
1029            win_count = 0
1030            for col in ["HERO_1", "HERO_2", "HERO_3", "HERO_4", "HERO_5"]:
1031                win_count += (
1032                    df_hist[df_hist["RESULT"] == "WIN"][col].value_counts().get(hero, 0)
1033                )
1034            df_bar_1.at[index, "WIN COUNT"] = win_count
1035        df_bar_1["WINRATE"] = round(df_bar_1["WIN COUNT"] / df_bar_1["COUNT"] * 100, 2)
1036
1037        with tab_0:
1038            st.write("")
1039            st.markdown(
1040                '<div style="margin-left: 28px">Terdapat dua tab yang dapat diakses, yaitu:</div>',
1041                unsafe_allow_html=True,
1042            )
1043            st.write("")
1044            st.markdown(
1045                "1. **Popularitas Keseluruhan**:a Tab ini akan menampilkan ringkasan semua popularitas karakter yang ada dalam dataset. \n\n2. **Popularitas berdasarkan Jumlah Penggunaan**:a Tab ini akan menampilkan perbandingan popularitas karakter antara jumlah penggunaan sepanjang tahun 2019 sampai 2022."
1046            )
1047            st.write("")
1048
1049        with tab1:
1050            fig5 = px.bar(
1051                df_bar_1,
1052                x="COUNT",
1053                y="HERO",
1054                color="COUNT",
1055                orientation="h",
1056                color_continuous_scale="haline",
1057            )
1058            fig5.update_layout(
1059                title="                                         Popularitas Keseluruhan Karakter",
1060                xaxis_title="Jumlah digunakan",
1061            )
1062            fig5.update_xaxes(showgrid=True, gridwidth=1, linewidth=2)
1063            st.plotly_chart(fig5)
1064
1065            col0, col1, col2, col3 = st.columns((3, 20, 20, 3))
1066
1067            with col1.container(border=True):
1068                st.markdown("##### Karakter Terpopuler")
1069
1070                col11, col12, coldiv = st.columns((8.8, 5, 0.5))
1071                col11.metric("Posisi Pertama", df_bar_1["HERO"].iloc[0])
1072                col12.metric("Penggunaan", df_bar_1["COUNT"].iloc[0])
1073                col11.metric("Posisi Kedua", df_bar_1["HERO"].iloc[1])
1074                col12.metric("Penggunaan", df_bar_1["COUNT"].iloc[1])
1075                col11.metric("Posisi Ketiga", df_bar_1["HERO"].iloc[2])
1076                col12.metric("Penggunaan", df_bar_1["COUNT"].iloc[2])
1077
1078            with col2.container(border=True):
1079                st.markdown("##### Karakter Tidak Populer")
1080
1081                col11, col12, coldiv = st.columns((8.8, 5, 0.5))
1082                col11.metric("Posisi Pertama", df_bar_1["HERO"].iloc[-1])
1083                col12.metric("Penggunaan", df_bar_1["COUNT"].iloc[-1])
1084                col11.metric("Posisi Kedua", df_bar_1["HERO"].iloc[-2])
1085                col12.metric("Penggunaan", df_bar_1["COUNT"].iloc[-2])
1086                col11.metric("Posisi Ketiga", df_bar_1["HERO"].iloc[-3])
1087                col12.metric("Penggunaan", df_bar_1["COUNT"].iloc[-3])
1088            st.write("")
1089
1090        with tab2:
1091            fig6 = px.scatter(
1092                df_bar_1,
1093                x="COUNT",
1094                y="WINRATE",
1095                color="WINRATE",
1096                hover_name="HERO",
1097                color_continuous_scale="redor",
1098            )
1099            fig6.update_layout(
1100                title="                     Perbandingan Winrate Karakter dengan Jumlah Pertandingan",
1101                xaxis_title="Jumlah Pertandingan",
1102                yaxis_title="Persentase Kemenangan (%)",
1103            )
1104
1105            if (
1106                (exclude_tournament_popover == "No Filter")
1107                and (input_tournament_popover == "No Filter")
1108                and (input_team_popover == "No Filter")
1109                and (exclude_team_popover == "No Filter")
1110            ):
1111                fig6.add_shape(
1112                    type="circle",
1113                    x0=20,
1114                    x1=200,
1115                    y0=35,
1116                    y1=66,
1117                    line_width=0,
1118                    opacity=0.1,
1119                    fillcolor="lightcoral",
1120                )
1121                fig6.add_annotation(
1122                    x=390,
1123                    y=41,
1124                    text="<b>Uncommon Hero</b>",
1125                    font_size=20,
1126                    font_color="lightcoral",
1127                    showarrow=False,
1128                )
1129                fig6.add_annotation(
1130                    x=390,
1131                    y=39,
1132                    text="<b>under 200 pick</b>",
1133                    font_size=15,
1134                    font_color="lightcoral",
1135                    showarrow=False,
1136                )
1137
1138                fig6.add_shape(
1139                    type="circle",
1140                    x0=160,
1141                    x1=1600,
1142                    y0=42,
1143                    y1=58,
1144                    line_width=0,
1145                    opacity=0.1,
1146                    fillcolor="#b16bbf",
1147                )
1148                fig6.add_annotation(
1149                    x=1650,
1150                    y=57,
1151                    text="<b>Common Hero</b>",
1152                    font_size=20,
1153                    font_color="#b16bbf",
1154                    showarrow=False,
1155                )
1156                fig6.add_annotation(
1157                    x=1650,
1158                    y=55.2,
1159                    text="<b>winrate between 45% and 55%</b>",
1160                    font_size=15,
1161                    font_color="#b16bbf",
1162                    showarrow=False,
1163                )
1164
1165                fig6.add_shape(
1166                    type="circle",
1167                    x0=1700,
1168                    x1=2000,
1169                    y0=45,
1170                    y1=52,
1171                    line_width=0,
1172                    opacity=0.1,
1173                    fillcolor="#5872d2",
1174                )
1175                fig6.add_annotation(
1176                    x=1820,
1177                    y=45.3,
1178                    text="<b>Contested Hero</b>",
1179                    font_size=20,
1180                    font_color="#5872d2",
1181                    showarrow=False,
1182                )
1183                fig6.add_annotation(
1184                    x=1830,
1185                    y=43.3,
1186                    text="<b>over 1500 pick</b>",
1187                    font_size=15,
1188                    font_color="#5872d2",
1189                    showarrow=False,
1190                )
1191
1192                fig6.add_shape(
1193                    type="circle",
1194                    x0=40,
1195                    x1=135,
1196                    y0=62.7,
1197                    y1=65.2,
1198                    line_width=2.5,
1199                    line_color="gold",
1200                    opacity=0.5,

Showing the first 1,200 of 1250 lines. Download the file for the rest.