Automated stock diagrams with Python is actually a rather useful idea, if you want to see how your portfolio is distributed. Just by using 2 columnes – “Ticker” and “Shares” in a CSV file, you can obtain a lot of additional information about it. E.g., how it is diversified amongst different sectors and how much are your different shares worth. Once you obain the basic idea, you can go and create further useful analytical insides.
This is how a sample input file looks like:
Then we start creating the tasks by importing the libraries and reading the csv files:
1 2 3 4 5 6 7 8 9 10 11 |
import os import pandas as pd import yfinance as yf from datetime import datetime import matplotlib.pyplot as plt import squarify INPUT_FILE = os.path.join('input', 'stocks.csv') OUTPUT_DIR = 'output' os.makedirs(OUTPUT_DIR, exist_ok = True) |
Then we fetch data with yfinance into a dataframe and write the dataframe into a csv file:
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 |
try: # Read the CSV file df = pd.read_csv(INPUT_FILE) # Fetch stock data and add new columns industries = [] for index, row in df.iterrows(): try: stock = yf.Ticker(row['Ticker']) info = stock.info price = info.get('regularMarketPreviousClose',0) # Default to 0 if key is missing dividend = info.get('dividendRate', 0) # Default to 0 if key is missing industry = info.get('industry', 'Unknown') # Default to 'Unknown' if key is missing short_name = info.get('shortName','Unknown') except Exception as e: print(f"Error fetching data for {row['Ticker']}: {e}") price = 0.0 dividend = 0.0 industry = 'Unknown' df.at[index,'Price'] = price df.at[index, 'Dividend'] = dividend df.at[index, 'Name']= short_name industries.append(industry) # Add industries to the DataFrame df['Industry'] = industries # Calculate total investment and expected annual dividends df['Total Investment'] = (df['Shares']*df['Price']).round(0) df['Expected Dividends'] = (df['Shares']*df['Dividend']).round(2) #Add "SUM" row at the bottom of the DataFrame sum_row = { 'Ticker':'SUM', 'Shares':'', 'Price':'', 'Dividend':'', 'Industry':'', 'Total Investment':df['Total Investment'].sum().round(0), 'Expected Dividends':df['Expected Dividends'].sum().round(0), } df = pd.concat([df, pd.DataFrame([sum_row])], ignore_index = True) # Generate file name with today's date and time output_name = datetime.now().strftime('%Y%m%d_%H%M%S') output_file = os.path.join(OUTPUT_DIR, f'{output_name}_updated_stocks.csv') # Save the updated DataFrame to a new CSV file df.to_csv(output_file, index=False) print(f'Data saved to {output_file}') except FileNotFoundError: print(f'Error: The file {INPUT_FILE} was not found.') except Exception as e: print(f'Error: An unexpected error has occurred {e}!') |
The next step is to generate a pie chart for industries:
1 2 3 4 5 6 7 8 9 10 11 |
# Generate a pie chart for industries today = datetime.now().strftime('%Y%m%d') industry_data = df[df['Ticker'] != 'SUM'].groupby('Industry')['Total Investment'].sum() plt.figure(figsize=(8, 8)) plt.pie(industry_data, labels=industry_data.index, autopct='%1.1f%%', startangle=140) plt.title('Investment Distribution by Industry') plt.savefig(os.path.join(OUTPUT_DIR, f'{today}_industry_distribution.png')) print("Industry distribution chart saved.") print(f'{today}_industry_distribution.png') |
As a last step, we go with the treemap. The library squarify helps there:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Generate a treemap for investment sizes with a custom colormap investment_data = df[df['Ticker'] != 'SUM'] plt.figure(figsize=(12, 8)) cmap = plt.colormaps['tab20'] # Accessing 'tab20' colormap colors = [cmap(i) for i in range(len(investment_data))] # Generate distinct colors squarify.plot( sizes=investment_data['Total Investment'], label=investment_data['Ticker'], alpha=0.8, color=colors # Pass the custom colors here ) plt.title('Investment Proportion by Ticker') plt.axis('off') # Hide axes for treemap plt.savefig(os.path.join(OUTPUT_DIR, f'{today}_investment_treemap.png')) print(f"Investment treemap chart saved.\n{today}_investment_treemap.png") |
The GitHub code is here:
Enjoy it! 🙂