1

I often see this in the context of matplotlib and open-high-low-close, but I'm wondering if you can add a volume overlay within the pandas framework. The final graph we would want would be close to the first one here: (Matplotlib - Finance volume overlay )

Say we have a DataFrame like such:

                       num  rolling_30  rolling_10  rolling_60  Volume
Date
2015-06-23        0.000219    0.000149    0.000168    0.000183       2
2015-06-25        0.000489    0.000162    0.000200    0.000188       3
2015-07-01        0.000164    0.000163    0.000190    0.000186       1
2015-07-02        0.000190    0.000166    0.000190    0.000187       1
2015-07-03        0.000269    0.000171    0.000198    0.000180       1
2015-07-04        0.000935    0.000196    0.000282    0.000193       2
2015-07-08        0.000154    0.000196    0.000288    0.000188       1
2015-07-11        0.000274    0.000202    0.000305    0.000190       1
2015-07-13        0.000872    0.000228    0.000380    0.000201       9

How can we get the ['num','rolling_30','rolling_10','rolling_60'] line chart with the bottom of the chart listing the daily volume? I can do a secondary_y to get volume on the right, but honestly that looks terrible. Need it to be the traditional volume bar-graph at the bottom of the chart.

Community
  • 1
  • 1
user1610719
  • 1,275
  • 2
  • 18
  • 35

2 Answers2

1

The basic idea is to use .twinx to create a secondary y axis. Below is a short sample to do it. From the graph, you see that the left y axis is for price and moving averages, whereas the right y axis is for volumn.

import pandas as pd
import matplotlib.pyplot as plt

# your data
# ============================
print(df)


               num  rolling_30  rolling_10,  rolling_60  Volume
Date                                                           
2015-06-23  0.0002      0.0001       0.0002      0.0002       2
2015-06-25  0.0005      0.0002       0.0002      0.0002       3
2015-07-01  0.0002      0.0002       0.0002      0.0002       1
2015-07-02  0.0002      0.0002       0.0002      0.0002       1
2015-07-03  0.0003      0.0002       0.0002      0.0002       1
2015-07-04  0.0009      0.0002       0.0003      0.0002       2
2015-07-08  0.0002      0.0002       0.0003      0.0002       1
2015-07-11  0.0003      0.0002       0.0003      0.0002       1
2015-07-13  0.0009      0.0002       0.0004      0.0002       9

# plotting
# ===========================
fig, ax = plt.subplots(figsize=(10,8))
df.drop('Volume', axis=1).plot(ax=ax)
ax.legend(loc='best')
ax2 = ax.twinx()
df['Volume'].plot(kind='bar', ax=ax2, color='g', alpha=0.1)
ax2.set_ylim([0, ax2.get_ylim()[1] * 10])
ax2.legend(loc='best')

enter image description here

Jianxun Li
  • 24,004
  • 10
  • 58
  • 76
  • Hey, This doesn't seem to be working for me ( http://i.imgur.com/PldujAI.png ). I usually use 'ggplot' style, could that be causing issues? I only changed the alpha of the volume plot, and nothing else. – user1610719 Jul 14 '15 at 15:44
  • If I take out the twinx() and the second plot, the normal plot(rolling_XX) shows up fine, but seems to disappear when I add the second plot. – user1610719 Jul 14 '15 at 15:48
  • @user1610719 it shouldn't be the problem of ggplot. looks like nothing is plotted on ax=ax. can you double check your code and post the full code to reproduce this error? – Jianxun Li Jul 14 '15 at 15:49
  • Yea if I use plt.show() after the initial plot, the data shows up as expected. It's just the additional plotting that blanks out the line plot – user1610719 Jul 14 '15 at 15:55
  • Also, code is the exact same as yours except adding plt.show() at the end – user1610719 Jul 14 '15 at 15:59
  • I don't add it generally in the middle, just to test to see if it brings up the initial plot. After taking out the middle plt.show() and only using plt.show() at the end, I end up with the plot I linked you(Except the bottom is the correct alpha, because I just c+p your code) – user1610719 Jul 14 '15 at 16:04
  • @user1610719 yes, it is doesnt matter whether you have line or bar for 2nd ax – Jianxun Li Jul 14 '15 at 17:54
  • In this case, it does. If I change it to a line my graph works. The bar will not show both plots. – user1610719 Jul 14 '15 at 18:05
  • @user1610719 sorry, i use ipython notebook and i cannot reproduce the empty plot you saw. i cannot see any reason why changing the plot type matters in this case. – Jianxun Li Jul 14 '15 at 18:08
1

So while Jianxun's answer is probably completely correct, it won't work on my system. I am on Pandas .17 and the newest matplotlib. I'm also on a Macbook. Basically if I try to share an X axis with two graphs, a line and bar graph, the first instantiated graph disappears.

The best way I can think to fix this is simply by doing two graphs on one (subplots) and hiding the X axis of the top graph. Here's what I did:

        fig = plt.figure(figsize=(10,6))
        ax1 = plt.subplot2grid((3,3), (0,0), colspan=3, rowspan=2)
        ax2 = plt.subplot2grid((3,3), (2,0), colspan=3)
        ax2.yaxis.tick_right()
        ax1.axes.get_xaxis().set_visible(False)
        fig.subplots_adjust(hspace=0)
        pct.drop('Volume', axis=1).plot(ax=ax1)
        pct['Volume'].plot(kind='bar',ax=ax2, rot=75, legend=True)
        #Set-up the X axis to not show so many labels
        n = 6
        ticks = ax2.xaxis.get_ticklocs()
        ticklabels = [l.get_text() for l in ax2.xaxis.get_ticklabels()]
        ax2.xaxis.set_ticks(ticks[::n])
        ax2.xaxis.set_ticklabels(ticklabels[::n])
        plt.gcf().subplots_adjust(bottom=0.15)
user1610719
  • 1,275
  • 2
  • 18
  • 35