-
Notifications
You must be signed in to change notification settings - Fork 0
/
visualization.py
119 lines (100 loc) · 3.91 KB
/
visualization.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
import logging
from typing import Any, Dict, List
import networkx as nx
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def visualize_cluster(cluster_report: Dict[str, Any]) -> None:
"""
Visualize the cluster of Bitcoin addresses.
Args:
cluster_report (Dict[str, Any]): The report containing the cluster information.
"""
G = nx.Graph()
# Add nodes and edges based on the cluster information
# Add nodes and edges based on the cluster information
for address_info in cluster_report.get("addresses", []):
address = address_info.get("address")
if address:
G.add_node(address)
transactions_flow = address_info.get("transactions_flow", [])
for flow in transactions_flow:
for tx in flow:
if isinstance(tx, dict):
txid = tx.get("txid")
if txid:
G.add_node(txid)
G.add_edge(address, txid)
for output in tx.get("outputs", []):
output_address = output.get("address")
if output_address:
G.add_node(output_address)
G.add_edge(txid, output_address)
# Draw the graph
plt.figure(figsize=(12, 12))
pos = nx.spring_layout(G, k=0.3)
nx.draw(G, pos, with_labels=True, node_size=500, node_color="skyblue", font_size=8, font_weight="bold", edge_color="gray")
plt.title("Bitcoin Address Cluster")
plt.show()
def plot_balance_over_time(address_info: Dict[str, Any]) -> None:
"""
Plot the balance of a Bitcoin address over time.
Args:
address_info (Dict[str, Any]): The address information containing transaction history.
"""
if "address" not in address_info:
logger.error("Address information is missing 'address' key")
return
transactions = address_info.get("transactions_flow", [])
balance = 0
balance_history = []
timestamps = []
for tx in transactions:
tx_time = tx.get('time', 0)
for output in tx.get("outputs", []):
if output.get("address") == address_info["address"]:
balance += output.get("value", 0)
for input_tx in tx.get("inputs", []):
if input_tx.get("prevout", {}).get("scriptpubkey_address") == address_info["address"]:
balance -= input_tx.get("prevout", {}).get("value", 0)
balance_history.append(balance)
timestamps.append(pd.to_datetime(tx_time, unit='s'))
plt.figure(figsize=(10, 5))
plt.plot(timestamps, balance_history, label='Balance over time')
plt.xlabel('Time')
plt.ylabel('Balance (BTC)')
plt.title(f"Balance over time for {address_info['address']}")
plt.legend()
plt.show()
def plot_transaction_values(transactions: List[Dict[str, Any]]) -> None:
"""
Plot a histogram of transaction values.
Args:
transactions (List[Dict[str, Any]]): List of transactions.
"""
values = []
for tx in transactions:
for output in tx.get("outputs", []):
values.append(output.get("value", 0))
plt.figure(figsize=(10, 5))
plt.hist(values, bins=50, log=True)
plt.xlabel('Transaction Value (BTC)')
plt.ylabel('Frequency')
plt.title('Histogram of Transaction Values')
plt.show()
def plot_degree_distribution(G: nx.Graph) -> None:
"""
Plot the degree distribution of the graph.
Args:
G (nx.Graph): The graph to plot the degree distribution for.
"""
degrees = [G.degree(n) for n in G.nodes()]
plt.figure(figsize=(10, 5))
plt.hist(degrees, bins=50, log=True)
plt.xlabel('Degree')
plt.ylabel('Frequency')
plt.title('Degree Distribution')
plt.show()