I want to insert some vertical dashed lines in my plot. I use the following code, and I face the error " ValueError: view limit minimum -34758.04999999988 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 ". Here is a sample of my data.
Date M
2013-03-13 0.727195
2013-03-14 0.727195
2013-03-15 0.727195
2013-03-16 0.727195
2013-03-17 0.727195
... ...
2018-11-12 0.115674
2018-11-13 -0.427214
2018-11-14 -0.389715
2018-11-15 0.427149
2018-11-16 -0.416864
[2075 rows x 1 columns]
and this is my code
import pandas as pd
from datetime import datetime, timedelta
from matplotlib import pyplot as plt
from matplotlib import dates as mpl_dates
data=pd.read_excel('ff.xlsx')
data['Date']=pd.to_datetime(data['Date'], format="%Y-%m-%d")
date = data['Date']
amount = data['M']
data.set_index('Date', inplace=True, drop=True)
plt.plot(date,amount, color='blue')
ax = plt.axes()
ax.yaxis.grid()
plt.ylabel('dvv percentage')
xposition = [2015-11-11, 2014-11-11]
for xc in xposition:
plt.axvline(x=xc, color='k', linestyle='--')
plt.show()
this should work:
from matplotlib import pyplot as plt
import pandas as pd
# example df:
df = pd.DataFrame({'Date':['2013-03-13','2015-03-14','2019-03-15'],
'M':[0.727195, -0.727195, 0.669195]})
# ensure datetime:
df['Date'] = pd.to_datetime(df['Date'])
ax = plt.plot(df.Date, df.M, color='blue')
ax = plt.axes()
ax.yaxis.grid()
plt.ylabel('dvv percentage')
# vertical line position as datetime dtype:
xposition = pd.to_datetime(['2015-11-11', '2014-11-11'])
for xc in xposition:
ax.axvline(x=xc, color='k', linestyle='--')
plt.show()
Related
I'm trying to figure out how to plot an X-axis with hourly precision (the index column has hourly values) as is in my dataframe. Currently, it just labels each month. I want one label for each Y point “close values column”.
My code now:
import matplotlib.pyplot as plt
from matplotlib import dates as mpl_dates
import pandas as pd
data = pd.read_csv('C:/Users/renat/.spyder-py3/1H data new.csv', index_col=0, parse_dates=True)
data.index = pd.to_datetime(data.index, format='%Y-%m-%d %H:%M:%S')
plt.figure(figsize=(80, 8))
plt.plot_date(data.index,data['close'], linestyle='solid',xdate=True, marker=None)
plt.gcf().autofmt_xdate()
date_format = mpl_dates.DateFormatter('%Y-%m-%d %H')
plt.gca().xaxis.set_major_formatter(date_format)
plt.title('Price Chart for TEST')
plt.xlabel('Date')
plt.ylabel('Price ($)')
plt.show()
Thanks to #r-begginers's comment I am able to achieve what I want. My finished code to print financial data with hourly labels for the X axis is as follows:
import matplotlib.pyplot as plt
from matplotlib import dates as mpl_dates
import pandas as pd
data = pd.read_csv('C:/Users/renat/.spyder-py3/1H data new.csv', index_col=0, parse_dates=True)
data.index = pd.to_datetime(data.index, format='%Y-%m-%d %H:%M:%S')
plt.figure(figsize=(100, 8))
plt.plot_date(data.index,data['close'], linestyle='solid',xdate=True, marker=None)
days = mpl_dates.DayLocator(interval=1)
days_fmt = mpl_dates.DateFormatter('%Y-%m-%d %H:%M')
plt.gca().xaxis.set_major_locator(days)
plt.gca().xaxis.set_major_formatter(days_fmt)
plt.grid()
plt.xticks(rotation=90, fontsize=6)
plt.title('Price Chart for TEST')
plt.xlabel('Date')
plt.ylabel('Price ($)')
plt.show()
I've simply replaced the three lines that were related to the formatting of the x-axis.
In:
hours = mpl_dates.HourLocator(interval=1)
hours_fmt = mpl_dates.DateFormatter('%H')
plt.gca().xaxis.set_major_locator(hours)
plt.gca().xaxis.set_major_formatter(hours_fmt)
Out:
plt.gcf().autofmt_xdate()
date_format = mpl_dates.DateFormatter('%Y-%m-%d %H')
plt.gca().xaxis.set_major_formatter(date_format)
I've also made some other changes, but they are not relevant to the question.
Thanks again to #r-begginers for pointing me in this direction.
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'])
I have tried plt.gcf().autofmt_xdate() but that doesn't fix the overlapping dates on the x axis. How do I clean the x axis to every week instead of everyday?
# Convert string column into date
df['date'] = pd.to_datetime(df['date'], format = "%Y-%m-%d")
plt.figure(figsize=(14,10))
plt.title("Daily Tests")
plt.ylabel("Number of confirmed cases")
plt.xlabel("Date")
sns.barplot(x=df['date'], y=df['confirmed'])
plt.show()
The graph:
any suggestions would be appreciated.
Set the interval of mdates.DayLocator(interval=14) in order to control the time series data of x-axis. In this case, it is set to two weeks.
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
fig = plt.figure(figsize=(14,10))
ax = fig.add_subplot(111)
sns.barplot(x=df['date'], y=df['confirmed'], ax=ax)
ax.set_title("Daily Tests")
ax.set_ylabel("Number of confirmed cases")
ax.set_xlabel("Date")
days = mdates.DayLocator(interval=14)
days_fmt = mdates.DateFormatter('%m-%d')
ax.xaxis.set_major_locator(days)
ax.xaxis.set_major_formatter(days_fmt)
plt.show()
I have a plot_graph() function that plots pandas dataframe as a line chart.
def plot_graph(df):
ax = plt.gca()
#df["Date"].dt.strftime("%m/%d/%y")
#df["date"] = df["date"].astype('datetime64[ns]')
print(df['date'])
df.plot(kind='line', x='date', y='Actual', ax=ax)
df.plot(kind='line', x='date', y='Expected', color='red', ax=ax)
ax.xaxis.set_major_locator(plt.MaxNLocator(3))
plt.savefig("fig1.png")
I pass pandas dataframe in this format
date actual expected
2019-11 20 65
2019-12 35 65
When I plot the line chart, x axis labels does not get displayed correctly as in (yyyy-mm) format. I believe it is with the date format. So I tried converting it to date. I tried with all the options(commented in the code), nothing seems to work. Any suggestions would be appreicated.
Try this:
import pandas as pd
import matplotlib.dates as mdates
def plot_graph(df):
ax = plt.gca()
df['date'] = pd.to_datetime(df['date']).dt.date
df.plot(kind='line', x='date', y='actual', ax=ax)
df.plot(kind='line', x='date', y='expected', color='red', ax=ax)
ax.xaxis.set_major_locator(mdates.MonthLocator())
# ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m')) #to explicitly set format
plot_graph(df)
I think using matplotlib.dates is the best thing here, but it seems like df.plot() needs dates to be date and not datetime (or string). If you instead plot directly through matplotlib you don't need to do this. More here.
Reference Matplotlib: Date tick labels & Formatting date ticks using ConciseDateFormatter
matplotlib.dates.MonthLocator
matplotlib.dates.DateFormatter
matplotlib.axis.Axis.set_major_locator
matplotlib.axis.XAxis.set_major_formatter
Note the index column is in a datetime format. To transform your column to datetime, use df.date = pd.to_datetime(df.date)
df.plot() has tick locs like array([13136, 13152, 13174, 13175], dtype=int64). I don't actually know how those numbers are derived, but they cause an issue with some of the matplotlib axis and date formatting methods, which is why I changed the plots away from df.plot.
sns.lineplot and plt.plot have tick locs that are the ordinal representation of the datetime, array([737553., 737560., 737567., 737577., 737584., 737591., 737598., 737607.].
import pandas as pd
import numpy as np # for test data
from datetime import datetime # for test data
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
# synthetic data with date as a datetime
np.random.seed(365)
length = 700
df = pd.DataFrame(np.random.rand(length, 2) * 10, columns=['Actual', 'Expected'], index=pd.bdate_range(datetime.today(), freq='d', periods=length).tolist()).reset_index()
# display(df.head())
index Actual Expected
0 2020-07-16 9.414557 6.416027
1 2020-07-17 6.846105 5.885621
2 2020-07-18 5.438872 3.680709
3 2020-07-19 7.666258 3.050124
4 2020-07-20 4.420860 1.104433
# function
def plot_graph(df):
# df.date = pd.to_datetime(df.date) # if needed and date is the column name
fig, ax = plt.subplots()
months = mdates.MonthLocator() # every month
months_fmt = mdates.DateFormatter('%Y-%m') # format
ax.plot('index', 'Actual', data=df)
ax.plot('index', 'Expected', data=df, color='red')
# format the ticks
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(months_fmt)
plt.xticks(rotation=90)
plt.legend()
plt.show()
plot_graph(df)
I am trying to plot a bar chart with the date vs the price of a crypto currency from a dataframe and have 731 daily samples. When i plot the graph i get the image as seen below. Due to the amount of dates the x axis is unreadable and i would like to make it so it only labels the 1st of every month on the x-axis.
This is the graph i currently have: https://imgur.com/a/QVNn4Zp
I have tried using other methods i have found online both in stackoverflow and other sources such as youtube but had no success.
This is the Code i have so far to plot the bar chart.
df.plot(kind='bar',x='Date',y='Price in USD (at 00:00:00 UTC)',color='red')
plt.show()
One option is to plot a numeric barplot with matplotlib.
Matplotlib < 3.0
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
start = pd.to_datetime("5-1-2012")
idx = pd.date_range(start, periods= 365)
df = pd.DataFrame({'Date': idx, 'A':np.random.random(365)})
fig, ax = plt.subplots()
dates = mdates.date2num(df["Date"].values)
ax.bar(dates, df["A"], width=1)
loc = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(loc))
plt.show()
Matplotlib >= 3.0
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
pd.plotting.register_matplotlib_converters()
start = pd.to_datetime("5-1-2012")
idx = pd.date_range(start, periods= 365)
df = pd.DataFrame({'Date': idx, 'A':np.random.random(365)})
fig, ax = plt.subplots()
ax.bar(df["Date"], df["A"], width=1)
plt.show()
Further options:
For other options see Pandas bar plot changes date format