1

I am having an issue getting my x axis tick labels to rotate. I have tried following the matplotlib documentation for axes.set_xticklabels() using ax1.set_xticklables(labels, rotation=45). I have tried using plt.setp per this post but still havent been able to successfully rotate the labels. For reference my code is as follows:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import datetime 

print("Enter a symbol:")
symbol = input()
symbol = symbol.upper()
print("Enter an interval:")
interval = input()
print("You entered: " + symbol)

# Obtain minute bars of symbol from Google Finance for the last ten days

bars = pd.read_csv(r'http://www.google.com/finance/getprices?i={}&p=10d&f=d,o,h,l,c,v&df=cpct&q={}'.format(interval, symbol), sep=',', engine='python', skiprows=7, header=None, names=['Date', 'Close', 'High', 'Low', 'Open', 'Volume'])

bars['Date'] = bars['Date'].map(lambda x: int(x[1:]) if x[0] == 'a' else int(x))
bars['Date'] = bars['Date'].map(lambda u: u * 60 if u < 400 else u)
threshold = 24000
bars['Timestamp'] = bars[bars['Date']>threshold].loc[:, 'Date']
bars['Timestamp'] = bars['Timestamp'].fillna(method='ffill')
bars['Date'] = bars.apply(lambda x: x.Date + x.Timestamp if x.Date < threshold else x.Date, axis=1)
bars.drop('Timestamp', axis=1, inplace=True)
bars['Date'] = bars['Date'].map(lambda v: datetime.datetime.fromtimestamp(v) if v < 25000 else datetime.datetime.fromtimestamp(v))

# Plot equity curve
fig = plt.figure()
fig.patch.set_facecolor('white') # Set the outer color to white
ax1 = fig.add_subplot(211, ylabel='Price in $')
ax1.set_xticklabels(bars['Date'], rotation=45)

# Plot the DIA closing price overlaid with the moving averages
bars['Close'].plot(ax=ax1, color='r', lw=2.)
signals[['short_mavg', 'long_mavg']].plot(ax=ax1,lw=2.)

# Plot the "buy" trades agains DIA
ax1.plot(signals.ix[signals.positions == 1.0].index, signals.short_mavg[signals.positions == 1.0], '^', markersize=10, color='m')
ax1.plot(signals.ix[signals.positions == 2.0].index, signals.short_mavg[signals.positions == 2.0], '^', markersize=10, color='m')

# Plot the "sell" trades against AAPL
ax1.plot(signals.ix[signals.positions == -1.0].index, signals.short_mavg[signals.positions == -1.0], 'v', markersize=10, color='b')
ax1.plot(signals.ix[signals.positions == -2.0].index, signals.short_mavg[signals.positions == -2.0], 'v', markersize=10, color='b')

# Plot the equity curve in dollars
ax2 = fig.add_subplot(212, xticklabels=bars['Date'], ylabel='Portfolio value in $')
ax2.set_xticklabels(bars['Date'], rotation=45)
returns['total'].plot(ax=ax2, lw=2.)

# Plot the "buy" and "sell" trades against the equity curve
ax2.plot(returns.ix[signals.positions == 1.0].index, returns.total[signals.positions == 1.0], '^', markersize=10, color='m')
ax2.plot(returns.ix[signals.positions == -1.0].index, returns.total[signals.positions == -1.0], 'v', markersize=10, color='b')
ax2.plot(returns.ix[signals.positions == 2.0].index, returns.total[signals.positions == 2.0], '^', markersize=10, color='m')
ax2.plot(returns.ix[signals.positions == -2.0].index, returns.total[signals.positions == -2.0], 'v', markersize=10, color='b')

# Plot the figure
fig.savefig("C:/users/gph/desktop/tradingalgorithm/30_60EMA_cross_backtest.png")

bars['Date'] is a dataframe column imported from a csv on my machine, but you could replicate a smaller version of it with the segment of code in the top of the example.

Community
  • 1
  • 1
Grr
  • 15,553
  • 7
  • 65
  • 85
  • I can't replicate your problem - this all works as expected for me if I rotate ticks (tried `datetime`, string and int types for labels). It's a little hard to help as your code sample is not an [MCVE](http://stackoverflow.com/help/mcve). If you add in a sample of what `bars` is, we might be able to help. It would be particularly helpful if you could add your imports as well, so we can just copy and paste into an editor and run it. Python version and matplotlib version might be relevant too. – J Richard Snape Jan 07 '16 at 17:12
  • 1
    @JRichardSnape Ok good point. I've edited my question. – Grr Jan 07 '16 at 17:16
  • OK - took a little time to find a working combo - use `CALL` for symbol and `10` for interval. Had to comment out `symbol` and `return`, but it plotted the price timeseries with rotated x tick labels just fine: http://i.stack.imgur.com/rWzMZ.png Obviously there are other formatting issues, but the rotation seems to work? – J Richard Snape Jan 07 '16 at 17:41
  • hmm. Thats odd. So you didnt have to change anything except commenting out `return` and i'm guessing you meant `signals` not `symbol`. Ill give it a go. What version of matplot are you using? – Grr Jan 07 '16 at 18:08
  • @JRichardSnape So from what i have tested so far it looks like the issue is occuring whenever line data is fed into the graph. As these are being plotted using pandas dataframe.plot() the issue may not be matplot related. Frustrating though as this is the second issue I have had with pandas now since upgrading to 0.17 from 0.15. – Grr Jan 07 '16 at 19:19
  • I'm no longer on same computer, so can't check which matplolib and pandas versions I used - will check when I can. You made the right assumption about my typo on what I commented out. – J Richard Snape Jan 07 '16 at 22:52

1 Answers1

1

So after a bit of tinkering I figured this out on my own. For some reason with Pandas 0.17 and matplotlib 1.5 trying to plot lines with df['column'].plot(ax=ax#) prevents me being able to control the formatting of the axis. Furthermore what i was doing with ax1.set_xticklabels(bars['Date'], rotation=45) was incorrect in that it was setting the ticklabels to the entirety of the 'Date' column and only displaying the first few based on the number of ticks.

What i ended up doing was following the advice of this post, converting the 'Date' from numpy.datetime64 (not friendly with matplotlib) to a float days format, and create a new column 'Dates' with this value. Then a list of unique days is created and converted to ISO date format.

dates = [md.date2num(t) for t in bars.Date]
bars['Dates'] = dates
days = np.unique(np.floor(bars['Dates']), return_index=True)
iso_days= []
for n in np.arange(len(days[0])):
    iso_days.append(datetime.date.isoformat(md.num2date(days[0][n]))) 

The rest was pretty simple, I made a few changes to the way I called subplots() and set sharex=True for looks.

# Plot two subplots to assess trades and equity curve. 
fig, (ax1, ax2) = plt.subplots(, 1, sharex=True)
fig.patch.set_facecolor('white') # Set the outer color to white
ax1.set_ylabel('Price in $')
# Plot the DIA closing price overlaid with the moving averages
ax1.set_xticks(days[1])

ax1.plot(bars.index, bars['Close'], color='r', lw=2.)
ax1.plot(bars.index, signals['short_mavg'], 'b', bars.index, signals['long_mavg'], 'g',lw=2.)

# Plot the "buy" trades agains DIA
ax1.plot(signals.ix[signals.positions == 1.0].index, signals.short_mavg[signals.positions == 1.0], '^', markersize=10, color='m')
ax1.plot(signals.ix[signals.positions == 2.0].index, signals.short_mavg[signals.positions == 2.0], '^', markersize=10, color='m')

# Plot the "sell" trades against AAPL
ax1.plot(signals.ix[signals.positions == -1.0].index, signals.short_mavg[signals.positions == -1.0], 'v', markersize=10, color='b')
ax1.plot(signals.ix[signals.positions == -2.0].index, signals.short_mavg[signals.positions == -2.0], 'v', markersize=10, color='b')

# Plot the equity curve in dollars
ax2.set_ylabel('Portfolio value in $')
ax2.plot(bars.index, returns.total, lw=2.)
ax2.set_xticklabels(iso_days, rotation=45, horizontalalignment='right')

# Plot the "buy" and "sell" trades against the equity curve
ax2.plot(returns.ix[signals.positions == 1.0].index, returns.total[signals.positions == 1.0], '^', markersize=10, color='m')
ax2.plot(returns.ix[signals.positions == -1.0].index, returns.total[signals.positions == -1.0], 'v', markersize=10, color='b')
ax2.plot(returns.ix[signals.positions == 2.0].index, returns.total[signals.positions == 2.0], '^', markersize=10, color='m')
ax2.plot(returns.ix[signals.positions == -2.0].index, returns.total[signals.positions == -2.0], 'v', markersize=10, color='b')

# Plot the figure
plt.tight_layout()
plt.show()
fig.savefig("C:/users/gph/desktop/tradingalgorithm/{}_{}EMA_cross_backtest.png".format(short_window, long_window))

It Worked!

Community
  • 1
  • 1
Grr
  • 15,553
  • 7
  • 65
  • 85