rafhiromadoni's picture
Upload 2 files
c61f589 verified
import gradio as gr
import networkx as nx
import matplotlib
import matplotlib.pyplot as plt
import random
# Gunakan backend 'Agg' agar aman di server
matplotlib.use('Agg')
# ==========================================
# 1. PERSIAPAN DATA JARINGAN (SIMULASI TWITTER)
# ==========================================
# Kita membuat graf simulasi (Scale-free network) yang karakteristiknya
# sangat mirip dengan jaringan media sosial di dunia nyata.
def create_twitter_network():
# Membuat 75 akun (nodes)
G = nx.barabasi_albert_graph(75, 2, seed=42)
# Memberi nama unik bergaya Twitter
mapping = {i: f"@User_{i+1}" for i in range(75)}
G = nx.relabel_nodes(G, mapping)
return G
G = create_twitter_network()
# Mendapatkan daftar semua pengguna untuk dropdown
all_users = list(G.nodes())
# ==========================================
# 2. FUNGSI ANALISIS & VISUALISASI
# ==========================================
def analyze_network(target_user):
fig, ax = plt.subplots(figsize=(10, 8))
# Menentukan posisi setiap titik agar rapi
pos = nx.spring_layout(G, seed=42)
# Gambar semua garis koneksi (Retweet/Mention)
nx.draw_networkx_edges(G, pos, alpha=0.15, ax=ax)
# Logika untuk mewarnai target user dan koneksinya
node_colors = []
node_sizes = []
for node in G.nodes():
if node == target_user:
node_colors.append('#e74c3c') # Merah untuk user yang dipilih
node_sizes.append(400)
elif G.has_edge(target_user, node):
node_colors.append('#f39c12') # Oranye untuk akun yang berinteraksi dengannya
node_sizes.append(150)
else:
node_colors.append('#3498db') # Biru untuk akun lain
node_sizes.append(30)
nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_size=node_sizes, ax=ax)
# Beri label (nama) HANYA untuk user yang dipilih dan koneksi langsungnya agar tidak penuh
labels = {n: n for n in G.nodes() if n == target_user or G.has_edge(target_user, n)}
nx.draw_networkx_labels(G, pos, labels=labels, font_size=9, font_weight="bold", ax=ax)
ax.set_title("🌐 Peta Jaringan Interaksi Twitter", fontsize=14)
ax.axis('off')
fig.tight_layout()
# Hitung metrik jaringan (Degree Centrality untuk mencari influencer)
degree_dict = dict(G.degree())
top_influencer = max(degree_dict, key=degree_dict.get)
koneksi_target = degree_dict[target_user]
# Output teks analisis
analisis_teks = f"""
### πŸ“Š Hasil Analisis Jaringan
* **Top Influencer Global:** `{top_influencer}` (Akun dengan interaksi terbanyak di jaringan ini).
* **Status `{target_user}`:** Memiliki koneksi langsung dengan **{koneksi_target} akun lain**.
"""
return fig, analisis_teks
# ==========================================
# 3. ANTARMUKA GRADIO
# ==========================================
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("""
<h1 style='text-align: center;'>🐦 Twitter Network Analysis</h1>
<p style='text-align: center;'>Aplikasi <i>Social Network Analysis</i> untuk memetakan penyebaran informasi, melihat hubungan antar akun, dan mendeteksi <i>Key Opinion Leaders</i> (KOL) dalam sebuah percakapan.</p>
""")
with gr.Row():
total_nodes = G.number_of_nodes()
total_edges = G.number_of_edges()
gr.Textbox(value=f"{total_nodes} Akun", label="πŸ‘₯ Total Partisipan", interactive=False)
gr.Textbox(value=f"{total_edges} Interaksi", label="πŸ”„ Total Retweet/Mention", interactive=False)
gr.Markdown("---")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### πŸ” Investigasi Akun")
gr.Markdown("Pilih satu akun untuk melihat peta sebaran pengaruhnya (Koneksi tingkat pertama).")
# Dropdown dengan nilai default akun pertama
user_dropdown = gr.Dropdown(choices=all_users, value=all_users[0], label="Pilih Akun Twitter:")
# Tempat menampilkan teks kesimpulan analisis
out_text = gr.Markdown()
with gr.Column(scale=2):
# Tempat menampilkan grafik jaringan
out_plot = gr.Plot(label="Visualisasi Graf Network")
# Interaktivitas
user_dropdown.change(
fn=analyze_network,
inputs=user_dropdown,
outputs=[out_plot, out_text]
)
# Load pertama kali
demo.load(
fn=analyze_network,
inputs=user_dropdown,
outputs=[out_plot, out_text]
)
if __name__ == "__main__":
demo.launch()