dibend commited on
Commit
4a6abf3
·
verified ·
1 Parent(s): 57c6d3a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -0
app.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yfinance as yf
3
+ import matplotlib.pyplot as plt
4
+ import matplotlib.colors as mcolors
5
+ import numpy as np
6
+ import imageio
7
+ from datetime import datetime
8
+ from tempfile import TemporaryDirectory
9
+ import os
10
+
11
+ st.set_page_config(page_title="Bubble Market Cap Animation", layout="wide")
12
+ st.title("📊 Market Cap Bubble Animation")
13
+
14
+ tickers_input = st.text_input("Enter Tickers (comma-separated):", "AAPL,MSFT,GOOG,NVDA,AMZN")
15
+ start_date = st.date_input("Start Date", datetime(2021, 1, 1))
16
+ end_date = st.date_input("End Date", datetime.today())
17
+
18
+ if st.button("Generate Bubble Animation"):
19
+ tickers = [ticker.strip().upper() for ticker in tickers_input.split(",")]
20
+ data = {}
21
+ market_caps = {}
22
+ colors = {}
23
+
24
+ st.info("Fetching data...")
25
+ for ticker in tickers:
26
+ try:
27
+ t = yf.Ticker(ticker)
28
+ hist = t.history(start=start_date, end=end_date)
29
+ shares = t.info.get("sharesOutstanding", None)
30
+ if shares is None:
31
+ continue
32
+ hist["Market Cap"] = hist["Close"] * shares
33
+ data[ticker] = hist
34
+ market_caps[ticker] = hist["Market Cap"]
35
+ colors[ticker] = np.random.rand(3,) # RGB color
36
+ except Exception as e:
37
+ st.warning(f"Failed to load {ticker}: {e}")
38
+
39
+ if not data:
40
+ st.error("No valid data found.")
41
+ st.stop()
42
+
43
+ all_dates = sorted(set(date for series in market_caps.values() for date in series.index))
44
+ st.info(f"Rendering {len(all_dates)} frames...")
45
+
46
+ with TemporaryDirectory() as tmpdir:
47
+ filenames = []
48
+
49
+ for i, date in enumerate(all_dates[::max(1, len(all_dates)//30)]): # Max 30 frames
50
+ fig, ax = plt.subplots(figsize=(10, 6))
51
+ ax.set_xlim(0, 1)
52
+ ax.set_ylim(0, 1)
53
+ ax.axis('off')
54
+ ax.set_title(f"Market Cap on {date.date()}", fontsize=16)
55
+
56
+ for j, ticker in enumerate(data):
57
+ try:
58
+ cap = market_caps[ticker].get(date, 0)
59
+ if cap == 0 or np.isnan(cap):
60
+ continue
61
+ size = cap / 1e11 # normalize
62
+ ax.scatter(
63
+ x=0.1 + 0.8 * np.random.rand(),
64
+ y=0.1 + 0.8 * np.random.rand(),
65
+ s=1000 * size,
66
+ alpha=0.7,
67
+ color=colors[ticker],
68
+ label=ticker,
69
+ edgecolors='black'
70
+ )
71
+ ax.text(0.1 + 0.8 * np.random.rand(), 0.1 + 0.8 * np.random.rand(), ticker, fontsize=8)
72
+ except:
73
+ continue
74
+
75
+ filepath = os.path.join(tmpdir, f"frame_{i:03}.png")
76
+ plt.savefig(filepath, bbox_inches="tight")
77
+ filenames.append(filepath)
78
+ plt.close()
79
+
80
+ gif_path = os.path.join(tmpdir, "bubbles.gif")
81
+ with imageio.get_writer(gif_path, mode='I', duration=0.4) as writer:
82
+ for filename in filenames:
83
+ image = imageio.imread(filename)
84
+ writer.append_data(image)
85
+
86
+ st.image(gif_path, caption="Market Cap Bubble Animation", use_column_width=True)
87
+ with open(gif_path, "rb") as f:
88
+ st.download_button("Download GIF", f, "market_cap_bubbles.gif", "image/gif")