How to Add Legend for Specific Stock Chart using matplotlib? - python

I have this code to plot 3 game corporation stocks. But I want to give legend thus I can know which chart is for EA or for Take Two or for Activision.
from pandas_datareader import data as pdr
import yfinance as yf
import matplotlib.pyplot as plt
yf.pdr_override()
y_symbols = ['EA', 'TTWO', 'ATVI']
from datetime import datetime
startdate = datetime(2000,1,1)
enddate = datetime(2023,1,31)
data = pdr.get_data_yahoo(y_symbols, start=startdate, end=enddate)
#print(data)
#data['Close'].plot()
plt.figure(figsize=(20,10))
plt.plot(data.index, data['Close'])
plt.xlabel("Date")
plt.ylabel("Price (in USD)")
plt.title("Game Corporation Stock Price 1/1/00 - 1/1/23")
plt.show()
Thank You.

You can add the label argument to your plot command and then call plt.legend() e.g.:
plt.plot(data.index, data['Close'], label=data["Close"].columns)
plt.legend()

Related

Visualizing Market Closing Values in Python Using MatPlotLib and YahooFinance

#imports
import pandas as pd
import yfinance as yf
from datetime import date, timedelta
from matplotlib import pyplot as plt
import numpy as np
plt.style.use('fivethirtyeight')
#Get Albemarle Information
ALBINFO = yf.Ticker("ALB")
# Valid options are 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y,
# 5y, 10y and ytd.
print(ALBINFO.history(period="2y"))
#Graph the Close Values
plt.figure(figsize = (12.2,4.5))
plt.plot(ALBINFO['Close'], label = 'Close')
plt.xticks(rotation = 45)
plt.title('Close Price History')
plt.xlabel('Date')
plt.ylabel('Price USD')
plt.show()
I am writing this code on Python Visual Studio Code.
I am trying to be a graphical representation of the ALB closing stock price.
However, whenever I run the code, only a blank screen shows up.
The computer states that there is a problem with the line
plt.plot(ALBINFO['Close'], label = 'Close').
Could someone help understand what is wrong with this line?
Thank you
I coded the lines above and excepted a graph of closing prices but only got a blank graph.
You need to store a dataframe(object) in order to use it. In this case, ALBINFO is overwritten:
import pandas as pd
import yfinance as yf
from datetime import date, timedelta
from matplotlib import pyplot as plt
import numpy as np
plt.style.use('fivethirtyeight')
#Get Albemarle Information
ALBINFO = yf.Ticker("ALB")
# Valid options are 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y,
# 5y, 10y and ytd.
ALBINFO = ALBINFO.history(period="2y")
#Graph the Close Values
plt.figure(figsize = (12.2,4.5))
plt.plot(ALBINFO['Close'], label = 'Close')
plt.xticks(rotation = 45)
plt.title('Close Price History')
plt.xlabel('Date')
plt.ylabel('Price USD')
plt.show()

Matplotlib axvspan() function fills wrong date

When I want to use axvspan to fill the dates, It fills wrong area. I think it reversed axvspans. The reason for the problem may be the dataframe that I imported from World Bank. How can I fix it? Thank you.
import matplotlib.pyplot as plt
import matplotlib
from pandas_datareader import wb
import seaborn as sns
import pandas as pd
import datetime
start = datetime.datetime (2000,1,1)
end = datetime.datetime (2021,5,1)
ind = ['FM.LBL.BMNY.ZG',
'FR.INR.DPST'
]
df = wb.download(indicator=ind, country='CHN', start=start, end=end).dropna();df.reset_index(inplace=True)
df.columns = ['Country',
'Year',
'Broad money growth (annual %) - China',
'Deposit interest rate (%)'
]
df=df.sort_values(by='Year', ascending=True)
axes= df.plot(x='Year',subplots=True, figsize=(20,12), layout=(1,2), colormap='summer', legend=True)
for ax, col in zip(axes.flatten(), df.columns):
ax.axvspan('2007-1-12', '2009-6-1', color='teal', alpha=0.5,
label='2008 Crisis')
ax.axvspan('2019-12-1', '2020-2-1', color='orange', alpha=0.5,
label='Pandemic')
ax.set_title(col)
axes[0,0].set_title('Broad money growth (annual %) - China')
axes[0,0].invert_xaxis()
axes[0,0].legend(loc='upper left')
axes[0,0].set_ylabel('Percent(Annual)')
axes[0,0].invert_xaxis()
axes[0,1].set_title('Deposit interest rate (%)')
axes[0,1].invert_xaxis()
axes[0,1].legend(loc='upper left')
axes[0,1].set_ylabel('Percent(Annual)')
axes[0,1].invert_xaxis()
plt.suptitle("Financial Sector in China",fontweight="bold")
plt.show()
Correcting xaxis dtype in pandas.plot to correct vspan locations
The year column in df is an object not an int, so the xlim is (-1, 21) and the labels are formatted on top of those index locations. Therefore, when you go to place your vspan, the x location entered does not match those of the x axis. To fix this, simply make your year column an int and make your vspan in terms of years as ints.
import matplotlib.pyplot as plt
import matplotlib
from pandas_datareader import wb
import seaborn as sns
import pandas as pd
import datetime
import matplotlib.ticker as ticker
start = datetime.datetime (2000,1,1)
end = datetime.datetime (2021,5,1)
ind = ['FM.LBL.BMNY.ZG',
'FR.INR.DPST'
]
df = wb.download(indicator=ind, country='CHN', start=start, end=end).dropna();df.reset_index(inplace=True)
df.columns = ['Country',
'Year',
'Broad money growth (annual %) - China',
'Deposit interest rate (%)'
]
df=df.sort_values(by='Year', ascending=True)
df['Year'] = df['Year'].astype(int)
axes= df.plot(x='Year',subplots=True, figsize=(15,5), layout=(1,2), colormap='summer', legend=True)
for ax, col in zip(axes.flatten(), df.columns):
ax.axvspan(2007, 2009, color='teal', alpha=0.5, label='2008 Crisis')
ax.axvspan(2019, 2020, color='orange', alpha=0.5, label='Pandemic')
ax.set_title(col)
ax.set_xlim(2000, 2021)
ax.xaxis.set_major_locator(ticker.MultipleLocator(2))
axes[0,0].set_title('Broad money growth (annual %) - China')
axes[0,0].legend(loc='upper left')
axes[0,0].set_ylabel('Percent(Annual)')
axes[0,1].set_title('Deposit interest rate (%)')
axes[0,1].legend(loc='upper left')
axes[0,1].set_ylabel('Percent(Annual)')
plt.suptitle("Financial Sector in China",fontweight="bold")

Create space on right side of plot

It is hard to see the last datapoint on the chart when it is right next to the y-axis. I would like to create some space between my last data point and the right y-axis. Any idea how to create this space?
import pandas as pd
import numpy as np
import yfinance as yf
import pandas_datareader as pdr
import datetime as dt
import matplotlib.pyplot as plt
##Get stock price data
ticker = '^GSPC, AAPL'
#get data from YFinance
df = yf.download(ticker, period = "max" , interval = "1d")['Adj Close']
#Convert the 'Date' Index to 'Date' Column
df.reset_index(inplace=True)
df['GSPCpctchange'] = (df['^GSPC'] / df['^GSPC'].shift(1))-1
df['AAPLpctchange'] = (df['AAPL'] / df['AAPL'].shift(1))-1
df['10_percent_R'] = df['GSPCpctchange'].rolling(10).corr(df['AAPLpctchange'])
df['10_price_R'] = df['^GSPC'].rolling(10).corr(df['AAPL'])
df['Date'] = pd.to_datetime(df['Date'], format = '%Y/%m/%d')
# Assign this as index
df.set_index(['Date'], inplace=True)
#Chart S&P500 and AAPL 10D R on one chart
plt.style.use('classic')
fig, ax1 = plt.subplots(figsize=(13,9))
ax2 = ax1.twinx()
fig.suptitle('S&P500 10D Correlation with AAPL', fontsize=16)
ax1.set_xlabel('Date')
ax1.set_ylabel('S&P500', color="blue")
ax1.tick_params(axis='y', labelcolor="blue")
ax1.plot(df.loc['2019-01-01':'2021-02-27','^GSPC'], linewidth=3, color="blue")
ax2.set_ylabel('10D AAPL Correlation', color="navy") # we already handled the x-label with ax1
ax2.tick_params(axis='y', labelcolor="navy")
ax2.plot(df.loc['2019-01-01':'2021-02-27','10_percent_R'], color="orange")
ax2.plot(df.loc['2019-01-01':'2021-02-27','10_price_R'], color="navy")
ax1.grid()
plt.legend(['Percent R','Price R'], loc="upper left")
You can try like this:
ax1.set_xlim(['2019-01-01', '2021-03-01'])

Plotting time-series data from pandas results in ValueError

I'm using pandas DataFrame and matplotlib to draw three lines in the same figure. The data ought to be correct, but when I try to plot the lines, the code returns a ValueError, which is unexpected.
The detail error warning says: ValueError: view limit minimum -105920.979 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units
How to fix this error, and plot three lines in the same figure?
import pandas as pd
import datetime as dt
import pandas_datareader as web
import matplotlib.pyplot as plt
from matplotlib import style
import matplotlib.ticker as ticker
spot=pd.read_excel('https://www.eia.gov/dnav/pet/hist_xls/RWTCd.xls',sheet_name='Data 1',skiprows=2) #this is spot price data
prod=pd.read_excel('https://www.eia.gov/dnav/pet/hist_xls/WCRFPUS2w.xls',sheet_name='Data 1',skiprows=2) #this is production data
stkp=pd.read_excel('https://www.eia.gov/dnav/pet/hist_xls/WTTSTUS1w.xls',sheet_name='Data 1',skiprows=2) #this is stockpile data
fig,ax = plt.subplots()
ax.plot(spot,label='WTI Crude Oil Price')
ax.plot(prod,label='US Crude Oil Production')
ax.plot(stkp,label='US Crude Oil Stockpile')
plt.legend()
plt.show()
print(spot,prod,stkp)
I don't get an error running the code, though I have made a couple of adjustments to the import and the plot.
Update matplotlib and pandas.
If you're using Anaconda, at the Anaconda prompt, type conda update --all
Parse the 'Date' column to datetime and set it as the index.
Place the legend outside the plot
Set the yscale to 'log', because the range of numbers is large.
import pandas as pd
import matplotlib.pyplot as plt
spot=pd.read_excel('https://www.eia.gov/dnav/pet/hist_xls/RWTCd.xls', sheet_name='Data 1',skiprows=2, parse_dates=['Date'], index_col='Date') #this is spot price data
prod=pd.read_excel('https://www.eia.gov/dnav/pet/hist_xls/WCRFPUS2w.xls', sheet_name='Data 1',skiprows=2, parse_dates=['Date'], index_col='Date') #this is production data
stkp=pd.read_excel('https://www.eia.gov/dnav/pet/hist_xls/WTTSTUS1w.xls', sheet_name='Data 1',skiprows=2, parse_dates=['Date'], index_col='Date') #this is stockpile data
fig,ax = plt.subplots()
ax.plot(spot, label='WTI Crude Oil Price')
ax.plot(prod, label='US Crude Oil Production')
ax.plot(stkp, label='US Crude Oil Stockpile')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.yscale('log')
plt.show()

candlestick plot from pandas dataframe, replace index by dates

This code gives plot of candlesticks with moving averages but the x-axis is in index, I need the x-axis in dates.
What changes are required?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_finance import candlestick2_ohlc
#date format in data-> dd-mm-yyyy
nif = pd.read_csv('data.csv')
#nif['Date'] = pd.to_datetime(nif['Date'], format='%d-%m-%Y', utc=True)
mavg = nif['Close'].ewm(span=50).mean()
mavg1 = nif['Close'].ewm(span=13).mean()
fg, ax1 = plt.subplots()
cl = candlestick2_ohlc(ax=ax1,opens=nif['Open'],highs=nif['High'],lows=nif['Low'],closes=nif['Close'],width=0.4, colorup='#77d879', colordown='#db3f3f')
mavg.plot(ax=ax1,label='50_ema')
mavg1.plot(color='k',ax=ax1, label='13_ema')
plt.legend(loc=4)
plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
plt.show()
Output:
I also had a lot of "fun" with this in the past... Here is one way of doing it using mdates:
import pandas as pd
import pandas_datareader.data as web
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick_ohlc
import matplotlib.dates as mdates
ticker = 'MCD'
start = dt.date(2014, 1, 1)
#Gathering the data
data = web.DataReader(ticker, 'yahoo', start)
#Calc moving average
data['MA10'] = data['Adj Close'].rolling(window=10).mean()
data['MA60'] = data['Adj Close'].rolling(window=60).mean()
data.reset_index(inplace=True)
data['Date']=mdates.date2num(data['Date'].astype(dt.date))
#Plot candlestick chart
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = fig.add_subplot(111)
ax3 = fig.add_subplot(111)
ax1.xaxis_date()
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y'))
ax2.plot(data.Date, data['MA10'], label='MA_10')
ax3.plot(data.Date, data['MA60'], label='MA_60')
plt.ylabel("Price")
plt.title(ticker)
ax1.grid(True)
plt.legend(loc='best')
plt.xticks(rotation=45)
candlestick_ohlc(ax1, data.values, width=0.6, colorup='g', colordown='r')
plt.show()
Output:
Hope this helps.
Simple df:
Using plotly:
import plotly.figure_factory
fig = plotly.figure_factory.create_candlestick(df.open, df.high, df.low, df.close, dates=df.ts)
fig.show()
will automatically parse the ts column to be displayed correctly on x.
Clunky workaround here, derived from other post (if i can find again, will reference). Using a pandas df, plot by index and then reference xaxis tick labels to date strings for display. Am new to python / matplotlib, and this this solution is not so flexible, but it works basically. Also using a pd index for plotting removes the blank 'weekend' daily spaces on market price data.
Matplotlib xaxis index as dates
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_finance import candlestick2_ohlc
from mpl_finance import candlestick_ohlc
%matplotlib notebook # for Jupyter
# Format m/d/Y,Open,High,Low,Close,Adj Close,Volume
# csv data does not include NaN, or 'weekend' lines,
# only dates from which prices are recorded
DJIA = pd.read_csv('yourFILE.csv') #Format m/d/Y,Open,High,
Low,Close,Adj Close,Volume
print(DJIA.head())
fg, ax1 = plt.subplots()
cl =candlestick2_ohlc(ax=ax1,opens=DJIA['Open'],
highs=DJIA['High'],lows=DJIA['Low'],
closes=DJIA['Close'],width=0.4, colorup='#77d879',
colordown='#db3f3f')
ax1.set_xticks(np.arange(len(DJIA)))
ax1.set_xticklabels(DJIA['Date'], fontsize=6, rotation=-90)
plt.show()

Categories