I am trying to use matplotlib to graph stock prices against a datetime index.
So I have a graph that looks like this:
And I need it to look like this:
I think it might have something to do with xticks, but I cannot figure out how to make xticks work with a datetime index. Thanks for the help.
tesla['Open'].plot(title='Open Price', label = 'Tesla', figsize = (16, 6))
ford['Open'].plot(label = 'ford')
gm['Open'].plot(label = 'GM')
plt.legend()
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
Like this:
import pandas as pd
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame({'values':np.random.randint(0,1000,36)},index=pd.date_range(start='2014-01-01',end='2016-12-31',freq='M'))
fig,ax1 = plt.subplots()
plt.plot(df.index,df.values)
monthyearFmt = mdates.DateFormatter('%Y-%m')
ax1.xaxis.set_major_formatter(monthyearFmt)
_ = plt.xticks(rotation=45)
Output:
EDIT:
Let's use set_major_locator with MonthLocator
import pandas as pd
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame({'values':np.random.randint(0,1000,36)},index=pd.date_range(start='2014-01-01',end='2016-12-31',freq='M'))
fig,ax1 = plt.subplots()
plt.plot(df.index,df.values)
monthyearFmt = mdates.DateFormatter('%Y-%m')
ax1.xaxis.set_major_formatter(monthyearFmt)
ax1.xaxis.set_major_locator(mdates.MonthLocator([1,7]))
_ = plt.xticks(rotation=45)
Output:
Related
I want the x values to be "yyyy-mm" from 2016-01 to 2020-01 (interval per half year). However, tried many ways the x values still in a mess.
My code is as follows:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import matplotlib.dates as mdates
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
df = pd.read_csv('fcc-forum-pageviews.csv',index_col='date')
df = df[(df['value'] >= df['value'].quantile(0.025)) & (df['value'] <= df['value'].quantile(0.975))]
fig = plt.figure()
fig.set_figwidth(15)
fig.set_figheight(9)
ax = fig.add_subplot(1,1,1)
ax.set_title('Daily freeCodeCamp Forum Page Views 5/2016-12/2019')
ax.set_xlabel('Date')
ax.set_ylabel('Page Views')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.plot(df['value'],color='r')
The following is the result:
However, what I expected should be:
The dataset can be downloaded from here.Any help is highly appreciated.
After #r-beginners help, I have updated the code as follows:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import matplotlib.dates as mdates
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
df = pd.read_csv('fcc-forum-pageviews.csv',index_col='date')
df = df[(df['value'] >= df['value'].quantile(0.025)) & (df['value'] <= df['value'].quantile(0.975))]
df.index = pd.to_datetime(df.index)
fig = plt.figure()
fig.set_figwidth(15)
fig.set_figheight(9)
ax = fig.add_subplot(1,1,1)
ax.set_title('Daily freeCodeCamp Forum Page Views 5/2016-12/2019')
ax.set_xlabel('Date')
ax.set_ylabel('Page Views')
ax.set_xticks(range(len(df.index)))
ax.set_xticklabels(range(len(df.index)))
months = mdates.MonthLocator(interval=6)
months_fmt = mdates.DateFormatter('%Y-%m')
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(months_fmt)
ax.plot(df['value'], color='r')
now it can display the x values in 6-month interval. However, instead of starting from 2016-07 (the date from the dataframe), it starts from 1970-02. Any hints? Thanks.
Convert the date data to pd.to_datetime()
You can use MonthLocator to control it. The interval is set to 6 months.
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import matplotlib.dates as mdates
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
df = pd.read_csv('fcc-forum-pageviews.csv',index_col='date')
df = df[(df['value'] >= df['value'].quantile(0.025)) & (df['value'] <= df['value'].quantile(0.975))]
df.index = pd.to_datetime(df.index)
fig = plt.figure()
fig.set_figwidth(15)
fig.set_figheight(9)
ax = fig.add_subplot(1,1,1)
ax.set_title('Daily freeCodeCamp Forum Page Views 5/2016-12/2019')
ax.set_xlabel('Date')
ax.set_ylabel('Page Views')
# ax.set_xticks(range(len(df.index)))
# ax.set_xticklabels(range(len(df.index)))
# months = mdates.MonthLocator(interval=6)
# months_fmt = mdates.DateFormatter('%Y-%m')
# ax.xaxis.set_major_locator(months)
# ax.xaxis.set_major_formatter(months_fmt)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.plot(df['value'], color='r')
Please read on Xticks
From the docs
>>> locs, labels = xticks() # Get the current locations and labels.
>>> xticks(np.arange(0, 1, step=0.2)) # Set label locations.
>>> xticks(np.arange(3), ['Tom', 'Dick', 'Sue']) # Set text labels.
>>> xticks([0, 1, 2], ['January', 'February', 'March'],
... rotation=20) # Set text labels and properties.
>>> xticks([]) # Disable xticks.
Using matplotlib and mpl_finance to plot candlesticks. Data is in csv AAPL.
I want to show the x-axis as year and month only, i.e."yyyy-mmm", so:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_finance import candlestick2_ohlc
import matplotlib.dates as mdates
data = pd.read_csv('C:\\AAPL.csv', delimiter = "\t")
data = data.sort_values(['Date'], ascending=True)
data = data.tail(100)
fig = plt.figure(figsize=(6,4))
plt.ylim(60, 200)
ax1 = fig.add_subplot(111)
cl =candlestick2_ohlc(ax=ax1,opens=data['Open'],highs=data['High'],lows=data['Low'],closes=data['Close'],width=0.6)
ax1.set_xticks(np.arange(len(data)))
ax1.set_xticklabels(data['Date'], fontsize=10, rotation=90)
# every month of the year like 2008-Jan, 2008-Feb...
locator = mdates.MonthLocator()
fmt = mdates.DateFormatter('%Y-%b')
X = plt.gca().xaxis
X.set_major_locator(locator)
X.set_major_formatter(fmt)
plt.show()
It doesn't show anything.
Also tried below but doesn't work neither:
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
How can I have the x-axis only show the year and month??
Thank you.
Try following solution,
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates
data = pd.read_csv('C:\AAPL.csv')
data = data.sort_values(['Date'], ascending=True)
data = data.tail(100)
from matplotlib.dates import date2num, DayLocator, DateFormatter
data['Date'] = date2num(pd.to_datetime(data['Date']).tolist())
fig, ax=plt.subplots(figsize=(10, 10))
candlestick_ohlc(ax, data.as_matrix(),width=0.6)
ax.set(xlabel='AAPL')
ax.xaxis.set_major_locator(DayLocator())
ax.xaxis.set_major_formatter(DateFormatter('%Y-%b'))
ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=4))
plt.show()
Note: I have used candlestick_ohlc instead of candlestick2_ohlc.
Output :
I have the following pandas plot:
Is it possible to add '%' sign on the y axis not as a label but on the number. Such as it would show instead of 0.0 it would be 0.0% and so on for all the numbers?
Code:
import pandas as pd
from pandas import datetime
from pandas import DataFrame as df
import matplotlib
from pandas_datareader import data as web
import matplotlib.pyplot as plt
import datetime
end = datetime.date.today()
start = datetime.date(2020,1,1)
data = web.DataReader('fb', 'yahoo', start, end)
data['percent'] = data['Close'].pct_change()
data['percent'].plot()
Here is how you can use matplotlib.ticker:
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
plt.show()
Output:
You can now control the display format of the y-axis. I think it will be 0.0%.
yvals = ax.get_yticks()
ax.set_yticklabels(["{:,.1%}".format(y) for y in yvals], fontsize=12)
You can also use plt.gca() instead of using ax
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1.0))
I use some of these code but actually I need different output
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.finance import plot_day_summary_ohlc, volume_overlay
from matplotlib import dates
df = pd.read_csv("try_stock.csv")
x = df.set_index('Date')
x['t']=x.index.map(dates.datestr2num)
fig = plt.figure()
ax1 = plt.subplot2grid((4,1), (0,3), rowspan=3)
print (df.index)
print type(ef['t'])
plot_day_summary_ohlc(ax1, x[['t','Total TradedAmount','ClosePrice','Max. Price', 'Min. Price','Total Traded Shares','Total Transactions']].values, ticksize=3, colorup=u'k', colordown=u'r')
df = df.set_index('t')
volume_overlay(ax2, df['previousClosing'], df['closingPrice'], df['totalShare'], colorup=u'k', colordown=u'r', width=4, alpha=1.0)
ax1.xaxis_date()
ax2.xaxis_date()
plt.show()
Current out is like this:
Output shouldn't be like this
Output must be like this:
Output somehow look like this
I'm trying to adjust the formatting of the date tick labels of the x-axis so that it only shows the Year and Month values. From what I've found online, I have to use mdates.DateFormatter, but it's not taking effect at all with my current code as is. Anyone see where the issue is? (the dates are the index of the pandas Dataframe)
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
fig = plt.figure(figsize = (10,6))
ax = fig.add_subplot(111)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
basicDF['some_column'].plot(ax=ax, kind='bar', rot=75)
ax.xaxis_date()
Reproducible scenario code:
import numpy as np
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
rng = pd.date_range('1/1/2014', periods=20, freq='m')
blah = pd.DataFrame(data = np.random.randn(len(rng)), index=rng)
fig = plt.figure(figsize = (10,6))
ax = fig.add_subplot(111)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
blah.plot(ax=ax, kind='bar')
ax.xaxis_date()
Still can't get just the year and month to show up.
If I set the format after .plot , get an error like this:
ValueError: DateFormatter found a value of x=0, which is an illegal date. This usually occurs because you have not informed the axis that it is plotting dates, e.g., with ax.xaxis_date().
It's the same for if I put it before ax.xaxis_date() or after.
pandas just doesn't work well with custom date-time formats.
You need to just use raw matplotlib in cases like this.
import numpy
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas
N = 20
numpy.random.seed(N)
dates = pandas.date_range('1/1/2014', periods=N, freq='m')
df = pandas.DataFrame(
data=numpy.random.randn(N),
index=dates,
columns=['A']
)
fig, ax = plt.subplots(figsize=(10, 6))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.bar(df.index, df['A'], width=25, align='center')
And that gives me:
Solution with pandas only
You can create nicely formatted ticks by using the DatetimeIndex and taking advantage of the datetime properties of the timestamps. Tick locators and formatters from matplotlib.dates are not necessary for a case like this unless you would want dynamic ticks when using the interactive interface of matplotlib for zooming in and out (more relevant for time ranges longer than in this example).
import numpy as np # v 1.19.2
import pandas as pd # v 1.1.3
# Create sample time series with month start frequency, plot it with a pandas bar chart
rng = np.random.default_rng(seed=1) # random number generator
dti = pd.date_range('1/1/2014', periods=20, freq='m')
df = pd.DataFrame(data=rng.normal(size=dti.size), index=dti)
ax = df.plot.bar(figsize=(10,4), legend=None)
# Set major ticks and tick labels
ax.set_xticks(range(df.index.size))
ax.set_xticklabels([ts.strftime('%b\n%Y') if ts.year != df.index[idx-1].year
else ts.strftime('%b') for idx, ts in enumerate(df.index)])
ax.figure.autofmt_xdate(rotation=0, ha='center');
The accepted answer claims that "pandas won't work well with custom date-time formats", but you can make use of pandas' to_datetime() function to use your existing datetime Series in the dataframe:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import pandas as pd
rng = pd.date_range('1/1/2014', periods=20, freq='m')
blah = pd.DataFrame(data = np.random.randn(len(rng)), index=pd.to_datetime(rng))
fig, ax = plt.subplots()
ax.xaxis.set_major_formatter(DateFormatter('%m-%Y'))
ax.bar(blah.index, blah[0], width=25, align='center')
Will result in:
You can see the different available formats here.
I stepped into the same problem and I used an workaround to transform the index from date time format into the desired string format:
import numpy as np
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import pandas as pd
rng = pd.date_range('1/1/2014', periods=20, freq='m')
blah = pd.DataFrame(data = np.random.randn(len(rng)), index=rng)
fig = plt.figure(figsize = (10,6))
ax = fig.add_subplot(111)
# transform index to strings
blah_test = blah.copy()
str_index = []
for s_year,s_month in zip(blah.index.year.values,blah.index.month.values):
# build string accorind to format "%Y-%m"
string_day = '{}-{:02d}'.format(s_year,s_month)
str_index.append(string_day)
blah_test.index = str_index
blah_test.plot(ax=ax, kind='bar', rot=45)
plt.show()
which results in the following figure: