pyplot line plotting erratically - python

I got these 2 simple csv data but when plotting the 'mon' line gone strange toward the end.
When plotting one chart, it is fine but when the 2 charts plotted together the 'monarch' one goes strange.
Thanks in advance.
Here is the code
import pandas as pd
from matplotlib import pyplot as plt
def run_plot1():
df_ash = pd.read_csv('./data/ashburn.csv')
df_mon = pd.read_csv('./data/monarch1bed.csv')
plt.grid(True)
plt.plot(df_ash['Date'], df_ash['Ash1bed'], label='Ashburn 1 bed')
plt.plot(df_mon['Date'], df_mon['Mon1bed'], label='Monarch 1 bed')
plt.xlabel("Date")
plt.ylabel("Rate")
plt.style.use("fivethirtyeight")
plt.title("One Bed Comparison")
plt.legend()
plt.savefig('data/sample.png')
plt.tight_layout()
plt.show()
run_plot1()
and the csv datas:
Date,Ash1bed,Ash2bed,Ash3bed
08-01,306,402
22-01,181,286,349
05-02,176,281,336
19-02,188,293,369
04-03,201,306,402
18-03,209
01-04,217,394,492
15-04,209,354,455
29-04,197,302,387
13-05,205,326,414
27-05,217,362,473
10-06,390,532
08-07,415
22-07,415
05-08,415
19-08,415
15-09,290,452,594
and another :
Date,Mon1bed
08-01,230
05-02,160
19-02,160
04-03,190
18-03,190
01-04,260
15-04,260
29-04,260
13-05,300
27-05,330
10-06,330
24-06,350
08-07,350
22-07,350
05-08,350
19-08,350
02-09,350

The basic reason of erratic printout is that your Date columns
in both DataFrames are of string type.
Convert them to datetime:
df_ash.Date = pd.to_datetime(df_ash.Date, format='%d-%m')
df_mon.Date = pd.to_datetime(df_mon.Date, format='%d-%m')
But to have "reader friendly" X-axis labels, a number of additional
steps are required.
Start from necessary imports:
from pandas.plotting import register_matplotlib_converters
import matplotlib.dates as mdates
Then register matplotlib converters:
register_matplotlib_converters()
And to get proper printout, run:
fig, ax = plt.subplots() # figsize=(10, 6)
ax.grid(True)
ax.plot(df_ash['Date'], df_ash['Ash1bed'], label='Ashburn 1 bed')
ax.plot(df_mon['Date'], df_mon['Mon1bed'], label='Monarch 1 bed')
plt.xlabel("Date")
plt.ylabel("Rate")
plt.style.use("fivethirtyeight")
plt.title("One Bed Comparison")
plt.legend()
dm_fmt = mdates.DateFormatter('%d-%m')
ax.xaxis.set_major_formatter(dm_fmt)
plt.xticks(rotation=45);
For your data I got:

You should convert the date variable to a date format
df1.Date = pd.to_datetime(df1.Date, format='%d-%m')
df2.Date = pd.to_datetime(df2.Date, format='%d-%m')
plt.plot(df1.Date, df1.Ash1bed)
plt.plot(df2.Date, df2.Mon1bed)

Related

How to remove the first and last minor tick month labels on matplotlib?

I want to generate a chart with the 12 months of a year as the x-axis labels, i.e. 'Jan' to 'Dec', positioned in the middle between the major ticks. I used the code from https://matplotlib.org/3.4.3/gallery/ticks_and_spines/centered_ticklabels.html to create the x-axis. The x-axis created has an additional 'Dec' on the left and 'Jan' on the right, i.e. a total of 14 labels instead of 12 (see attached image). However, only 'Jan' to 'Dec' are wanted on the chart. I would like to know how to remove the 'Dec' label on the left and 'Jan' label on the right? My google searches were only successful with solutions to remove all minor tick labels. Any help will be much appreciated.
I use the following code to generate the chart:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
df = pd.DataFrame(np.random.randint(0,100,size=(365, 2)), columns=list('AB'))
df.index = pd.date_range(start='1/1/2022', end='12/31/2022').strftime('%b-%d')
plt.figure()
ax = plt.gca()
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_minor_locator(mdates.MonthLocator(bymonthday=16))
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b'))
for tick in ax.xaxis.get_minor_ticks():
tick.tick1line.set_markersize(0)
tick.tick2line.set_markersize(0)
tick.label1.set_horizontalalignment('center')
plt.plot(df['A'], linewidth=0.5, color='tab:red')
plt.show()
enter image description here
Try setting your x-axis limit to values between 0 and 365. Sometimes matplotlib uses values a little outside of your data. This way, the first Dec and last Jan are automatically eliminated from the plot.
Here I modified your code with 1 argument: plt.xlim(0,365)
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
df = pd.DataFrame(np.random.randint(0,100,size=(365, 2)), columns=list('AB'))
df.index = pd.date_range(start='1/1/2022', end='12/31/2022').strftime('%b-%d')
plt.figure()
ax = plt.gca()
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_minor_locator(mdates.MonthLocator(bymonthday=16))
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b'))
for tick in ax.xaxis.get_minor_ticks():
tick.tick1line.set_markersize(0)
tick.tick2line.set_markersize(0)
tick.label1.set_horizontalalignment('center')
plt.xlim(0,365)
plt.plot(df['A'], linewidth=0.5, color='tab:red')
plt.show()

X-Axis Labels from CSV?

I'm trying to make the labels of my graph correlate to the months column of a CSV file I've made, however when the program is run the graph prints perfectly but the months do not show on the x axis, just numbers. How do I fix this?
EDIT: The error it gives me is "ConversionError: Failed to convert value(s) to axis units"
My code:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
crimedata = pd.read_csv('MasterFileCSV.csv')
homicide = crimedata['Homicide Convictions'].values
robbery = crimedata['Robbery Convictions'].values
crimDamage = crimedata['Criminal Damage Convictions'].values
month = crimedata['month'].values
fig = plt.figure()
plt.xticks(month, rotation='vertical')
plt.plot(np.arange(len(homicide)), homicide, color='red', label='Homicide Convictions')
plt.plot(np.arange(len(robbery)), robbery, color='green', label='Robbery Convictions')
plt.plot(np.arange(len(crimDamage)), crimDamage, color='blue', label='Criminal Damage Convictions')
plt.legend(loc='best')
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()

Plotting candlestick with matplotlib for time series w/o weekend gaps

trying to plot a candlestick serie after importing datas from yahoo-finance. I'm using python 2.7
I have already a serie plotted and I want to add the same one as candlestick but I don't see how I can do that :
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ohlc
#Reset the index to remove Date column from index
df_ohlc = data.reset_index()
#Naming columns
df_ohlc.columns = ["Date","Open","High",'Low',"Close", "Adj Close", "Volume"]
#Normal plot
ax1 = plt.subplot()
ax1.plot(df_ohlc["Date"], df_ohlc["Close"], label = "Price", color="blue", linewidth=2.0)
#Candle plot
candlestick2_ohlc(ax1,df_ohlc['Open'],df_ohlc['High'],df_ohlc['Low'],df_ohlc['Close'],width=0.6)
If I plot candlestick alone, it looks fine but the x axis is a list of integers.
If I plot candlestick alone after converting df_ohlc["Date"] to float then reconverting to datetime, it plots the serie with the correct x axis but there are gaps on the weekend even if the serie isn't defined for these dates.
Is there a way to plot both series at the same time ? I'm planning to add more series like moving average, OLS, Bollinger etc...
You can remove weekend gaps and make human-readable dates xticklabels in this way. Note that, this script is written in python 3 and there may be some differences from python 2.
import quandl
import numpy as np
from mpl_finance import candlestick_ohlc
import matplotlib.pyplot as plt
# getting data and modifying it to remove gaps at weekends
r = quandl.get('WIKI/AAPL', start_date='2016-01-01', end_date='2017-11-10')
date_list = np.array(r.index.to_pydatetime())
plot_array = np.zeros([len(r), 5])
plot_array[:, 0] = np.arange(plot_array.shape[0])
plot_array[:, 1:] = r.iloc[:, :4]
# plotting candlestick chart
fig, ax = plt.subplots()
num_of_bars = 100 # the number of candlesticks to be plotted
candlestick_ohlc(ax, plot_array[-num_of_bars:], colorup='g', colordown='r')
ax.margins(x=0.0, y=0.1)
ax.yaxis.tick_right()
x_tick_labels = []
ax.set_xlim(right=plot_array[-1, 0]+10)
ax.grid(True, color='k', ls='--', alpha=0.2)
# setting xticklabels actual dates instead of numbers
indices = np.linspace(plot_array[-num_of_bars, 0], plot_array[-1, 0], 8, dtype=int)
for i in indices:
date_dt = date_list[i]
date_str = date_dt.strftime('%b-%d')
x_tick_labels.append(date_str)
ax.set(xticks=indices, xticklabels=x_tick_labels)
plt.show()
I really need more information about your code and your dataframe, but you can use this example to do a candlestick
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib.finance import candlestick_ohlc
import matplotlib.dates as mdates
import datetime as dt
#Reset the index to remove Date column from index
df_ohlc = df.reset_index()
#Naming columns
df_ohlc.columns = ["Date","Open","High",'Low',"Close", "Adj Close", "Volume"]
#Converting dates column to float values
df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num)
#Making plot
fig = plt.figure()
fig.autofmt_xdate()
ax1 = plt.subplot2grid((6,1), (0,0), rowspan=6, colspan=1)
#Converts raw mdate numbers to dates
ax1.xaxis_date()
plt.xlabel("Date")
print(df_ohlc)
#Making candlestick plot
candlestick_ohlc(ax1,df_ohlc.values,width=1, colorup='g', colordown='k',alpha=0.75)
plt.ylabel("Price")
plt.legend()
plt.show()

ploting subplot in matplotlib with pandas issue

i am try to plot subplot in matplotlib with pandas but there are issue i am facing. when i am plot subplot not show the date of stock...there is my program
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import pandas.io.data
df = pd.io.data.get_data_yahoo('goog', start=datetime.datetime(2008,1,1),end=datetime.datetime(2014,10,23))
fig = plt.figure()
r = fig.patch
r.set_facecolor('#0070BB')
ax1 = fig.add_subplot(2,1,1, axisbg='#0070BB')
ax1.grid(True)
ax1.plot(df['Close'])
ax2 = fig.add_subplot(2,1,2, axisbg='#0070BB')
ax2.plot(df['Volume'])
plt.show()
run this program own your self and solve date issue.....
When you're calling matplotlib's plot(), you are only giving it one array (e.g. df['Close'] in the first case). When there's only one array, matplotlib doesn't know what to use for the x axis data, so it just uses the index of the array. This is why your x axis shows the numbers 0 to 160: there are presumably 160 items in your array.
Use ax1.plot(df.index, df['Close']) instead, since df.index should hold the date values in your pandas dataframe.
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import pandas.io.data
df = pd.io.data.get_data_yahoo('goog', start=datetime.datetime(2008,1,1),end=datetime.datetime(2014,10,23))
fig = plt.figure()
r = fig.patch
r.set_facecolor('#0070BB')
ax1 = fig.add_subplot(2,1,1, axisbg='#0070BB')
ax1.grid(True)
ax1.plot(df.index, df['Close'])
ax2 = fig.add_subplot(2,1,2, axisbg='#0070BB')
ax2.plot(df.index, df['Volume'])
plt.show()

Categories