Automated Stock Diagrams with Python

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:

This is a simple input file. It means that we are having 50 shares from 3 companies – F, GOOG and AAPL.

Then we start creating the tasks by importing the libraries and reading the csv files:

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:

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:

# 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')
50 shares from 3 companies look like this into USD.

As a last step, we go with the treemap. The library squarify helps there:

# 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")
50 shares from 3 companies look like this into rectangulars (size of the rectangular is based on USD value of these 50 shares).

The GitHub code is here:

https://github.com/Vitosh/Python_personal/tree/master/YouTube/021_Python-And-Automated-Portfolio-Analysis

Automated Stocks Diagrams And Python

Enjoy it! 🙂