File size: 2,921 Bytes
4a6abf3 7bfdab4 4a6abf3 7bfdab4 59f38cb 4a6abf3 7bfdab4 1924724 4a6abf3 1924724 beac226 4842302 e8144d2 1924724 e8144d2 1924724 e8144d2 1924724 e8144d2 1924724 7bfdab4 e8144d2 1924724 e8144d2 1924724 59f38cb 1924724 59f38cb 1924724 59f38cb 1924724 59f38cb 1924724 59f38cb |
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 |
import streamlit as st
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
import imageio
from io import BytesIO
import tempfile
import math
st.set_page_config(layout="wide")
st.title("Market Cap Animation")
tickers_input = st.text_input("Tickers", "AAPL,MSFT,NVDA,GOOG,AMZN,META")
start_date_str = st.text_input("Start Date", "2021-01-01")
end_date_str = st.text_input("End Date", "2025-04-01")
def fetch_market_caps(tickers, start, end):
data = yf.download(tickers, start=start, end=end)["Close"]
if isinstance(data, pd.Series):
data = data.to_frame()
mcap = pd.DataFrame(index=data.index)
failed = []
for t in tickers:
try:
shares = yf.Ticker(t).info.get("sharesOutstanding", None)
if not shares or shares <= 0:
failed.append(t)
continue
mcap[t] = data[t] * shares / 1e6
except:
failed.append(t)
mcap.dropna(how="any", inplace=True)
return mcap.iloc[::5], failed
if st.button("Generate"):
tickers = [t.strip().upper() for t in tickers_input.split(",")]
start = pd.to_datetime(start_date_str)
end = pd.to_datetime(end_date_str)
mcap, failed = fetch_market_caps(tickers, start, end)
if mcap.empty:
st.error("No data.")
else:
frames = []
fig, ax = plt.subplots(figsize=(12, 6))
ordered = list(mcap.columns)
colors = {t: plt.cm.tab10(i % 10) for i, t in enumerate(ordered)}
# Grid layout dimensions
n = len(ordered)
cols = math.ceil(math.sqrt(n))
rows = math.ceil(n / cols)
# Fixed positions in a grid
grid_positions = {}
for i, t in enumerate(ordered):
row = i // cols
col = i % cols
x = col + 1
y = rows - row
grid_positions[t] = (x, y)
for date, row in mcap.iterrows():
ax.clear()
ax.axis("off")
ax.set_xlim(0, cols + 2)
ax.set_ylim(0, rows + 2)
ax.set_title(str(date.date()), fontsize=14)
for t in ordered:
val = row[t]
x, y = grid_positions[t]
ax.text(x, y, f"{t}\n{val:,.0f}M", fontsize=10,
ha='center', va='center',
bbox=dict(boxstyle="circle,pad=0.6", fc=colors[t], ec="black"))
buf = BytesIO()
plt.savefig(buf, format="png", bbox_inches="tight")
buf.seek(0)
frames.append(imageio.v2.imread(buf))
buf.close()
with tempfile.NamedTemporaryFile(delete=False, suffix=".gif") as tmp:
imageio.mimsave(tmp.name, frames, duration=2.5)
st.image(frames[-1])
st.download_button("Download GIF", open(tmp.name, "rb").read(),
file_name="market_cap.gif", mime="image/gif") |