0

I'm trying to duplicate my y axis so that it appears on both the left and the right side of my graph (same scale on each side). I believe the correct way to do this is through the twiny method, but cannot get my head round it. Here is my current code:

import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

def bar(data_df,
    colour_df=None,
        method='default',
        ret_obj=False):
    height = len(data_df.columns)*4
    width = len(data_df.index)/4
    ind = np.arange(len(data_df.index))
    dat = data_df[data_df.columns[0]]
    bar_width = 0.85
    fig, ax = plt.subplots(figsize=(width,height))
    ax1 = ax.bar(ind,dat,bar_width,color='y',log=True)
    ax2 = ax1.twiny()
    ax.tick_params(bottom='off', top='off', left='on', right='on') 
    plt.xticks(np.arange(len(data_df.index)) + bar_width, 
               data_df.index, rotation=67,ha='right')
    ylab = 'Region Length (base pairs, log10)'
    figname = 'bar' + method + '.png'
    if ret_obj==False:
        fig.savefig(figname,bbox_inches='tight',dpi=250)
        print "Output figure:", figname
        plt.close()
    if ret_obj==True:
        return fig

Which returns the following error when passed a dataframe:

AttributeError: 'BarContainer' object has no attribute 'twiny'

Having looked into it a bit further I believe that using the host/parasite methods would also work, but I'm a bit lost how I could fit it into my current code. Advice would be gratefully appreciated!

Community
  • 1
  • 1
s_boardman
  • 416
  • 3
  • 9
  • 27

1 Answers1

2

You don't have to use twiny in this case. It suffices to draw the labels on all sides:

bars = ax.bar(ind,dat,bar_width,color='y',log=True)
ax.tick_params(axis='both', which='both', labelbottom=True, labeltop=True, 
               labelleft=True, labelright=True)

I get following result with dummy data:

df = pd.DataFrame({"a": np.logspace(1,10,20)})
bar(df)

plot

cel
  • 30,017
  • 18
  • 97
  • 117
  • Awesome, cheers @cel. It does knock my ylab axis label out, assume I have to call it in a different way now? – s_boardman Jan 27 '15 at 14:05
  • 1
    @s_boardman, It appears that you did not set the label in your code. Adding `ax.set_ylabel(ylab)` seems to work fine. You do not want to have it on both sides, do you? – cel Jan 27 '15 at 14:12
  • that code did work for the previous version. But using 'ax.set_ylabel()' partially solves the problem for me. Thanks again! - Yup both sides would be ideal, can cope with just the left if necessary. – s_boardman Jan 27 '15 at 14:15