Blogs

Visualizing Historical Stock Prices with Matplotlib

Here's the imports:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
import pandas_datareader.data as pdr

Get data using pdr:

btc = pdr.DataReader('BTC-USD', 'yahoo', start='2018-07-12', end='2022-06-30')
eth = pdr.DataReader('ETH-USD', 'yahoo', start='2018-07-12', end='2022-06-30')

Visualize two assets horizontally in log scale for comparison:

fig, ax = plt.subplots(2, figsize=(12,10))
ax[0].plot(eth.index, eth['Close'], color = 'tab:blue')
ax[0].set_title('ETH')
ax[0].xaxis.set_major_locator(mdates.MonthLocator(interval=3))
ax[0].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax[0].xaxis.set_minor_locator(mdates.MonthLocator())
ax[0].set_yscale('log')
ax[0].yaxis.set_major_locator(ticker.LogLocator(base=2))
ax[0].yaxis.set_major_formatter(ticker.ScalarFormatter())
ax[0].grid()
plt.setp(ax[0].get_xmajorticklabels(), rotation=30, horizontalalignment='right')
ax[1].plot(btc.index, btc['Close'], color = 'tab:orange')
ax[1].set_title('BTC')
ax[1].xaxis.set_major_locator(mdates.MonthLocator(interval=3))
ax[1].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax[1].xaxis.set_minor_locator(mdates.MonthLocator())
ax[1].set_yscale('log')
ax[1].yaxis.set_major_locator(ticker.LogLocator(base=2))
ax[1].yaxis.set_major_formatter(ticker.ScalarFormatter())
ax[1].grid()
plt.setp(ax[1].get_xmajorticklabels(), rotation=30, horizontalalignment='right')
plt.tight_layout(pad=3.4, w_pad=0.5, h_pad=3.0)
plt.show()

 That looks like

For ploting a single asset with same settings simply:

fig, ax = plt.subplots(figsize=(12,10))
ax.plot(btc.index, 'Close', data=btc, label='BTC')
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=3))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.xaxis.set_minor_locator(mdates.MonthLocator())
fig.autofmt_xdate()
ax.set_yscale('log')
ax.yaxis.set_major_locator(ticker.AutoLocator())
ax.yaxis.set_major_formatter(ticker.ScalarFormatter())
ax.grid(True)
plt.show()

That looks like

 

Instead of plotting two graphs, normalize the prices and plot them in a single log scale graph for comparison:

fig = plt.figure(figsize=(12,10))
ax = fig.add_subplot(1,1,1)
plt.title('BTC vs. ETH')
(btc['Close']/btc.Close.iloc[0]).plot(label='BTC')
(eth['Close']/eth.Close.iloc[0]).plot(label='ETH')
plt.yscale('log')
plt.legend()
plt.show()

 

These were slightly processed version of a standard graph. A standard graph would looks like this:

fig = plt.figure(figsize=(12,10))
fig.suptitle("BTC & ETH")
ax1 = fig.add_subplot(2,1,1)
ax1.set_title('ETH')
ax1.plot(eth.index, eth['Close'], color = 'tab:blue')
ax2 = fig.add_subplot(2,1,2)
ax2.set_title('BTC')
ax2.plot(btc.index, btc['Close'], color = 'tab:orange')
plt.show()