Note: This is simply a guide on how to plot and read stock histograms using Python Pandas and Matplotlib. This is not an endorsement of any stock.

Histograms are used to display frequency distributions in a chart. Hence they are a great way to visualize return and volatility (risk) for stocks. Here is a histogram of daily returns for the S&P 500 for a sample date range in 2017:
Screenshot from 2018-05-27 16-18-02

The X-Axis is + / – change (%)
The Y-Axis is the number of occurrences.

– The white dotted line is the mean.
– The red dotted lines represent standard deviation. Just like in Bollinger Bands, wider standard deviation indicates more volatility.

Here is the code to calculate daily returns and then generate the histogram, where df is a pandas.DataFrame :

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as matplt

def calculate_daily_returns(df):
  daily_returns = (df / df.shift(1)) -1
  daily_returns.ix[0] = 0
  return daily_returns

def plot_histogram(df, bins):
  mean = df.mean(skipna=True)
  std = df.std(skipna=True)
  df.hist(bins=bins)
  plt.axvline(mean.item(), color='w', linestyle='dashed', linewidth=2)
  plt.axvline(std.item(), color='r', linestyle='dashed')
  plt.axvline(-std.item(), color='r', linestyle='dashed')
  plt.show()

A common use of histograms is to compare 2 or more stocks’ daily return volatility against each other. An example would be to compare Nvidia against the S&P 500 (let’s ignore the fact Nvidia trades in Nasdaq for the moment.)

Let’s say we have our initial DataFrame where we’ve joined SPY and NVDA adjusted close. The join result is structured like this:
Screenshot from 2018-05-27 17-04-06
We then put this SPY_NVDA DataFrame through our function to calulcate daily returns.

calculate_daily_returns(df)

The resulting dataframe is this:
Screenshot from 2018-05-27 17-07-54
Instead of two separate histograms, we want both of these results overlayed onto the same axes, since we want to compare each stock’s return and volatility against each other. Here is how to accomplish this:

df['NVDA'].hist(bins=bins, label="NVDA")
df['SPY'].hist(bins=bins, label="SPY")
plt.legend(loc='upper right')
plt.show()

Screenshot from 2018-05-27 17-19-30
In comparing the return and volatility of Nvidia against the S&P 500, we can determine the following:
Screenshot from 2018-05-27 17-36-16
1. Standard Deviation for Nvidia (indicated by solid red lines) is greater than Standard Deviation of the S&P 500 (indicated by solid yellow lines). This means NVidia is more volatile.

2. Mean for Nvidia (indicated by red dotted line) is slightly greater than the mean for the S&P 500 (indicated by yellow dotted line.) This shows the return for NVidia is slightly greater than the return for the S&P 500 (for our sample date range).