-1

Matplotlib axis with two scales shared origin

I have already tried to implement this the existing stackflow solution and my both x-axes are not aligning to 0. My Code :

def align_xaxis(ax1, v1, ax2, v2):
    """adjust ax2 xlimit so that v2 in ax2 is aligned to v1 in ax1"""
    x1, _ = ax1.transData.transform((v1, 0))
    x2, _ = ax2.transData.transform((v2, 0))
    inv = ax2.transData.inverted()
    dx, _ = inv.transform((0, 0)) - inv.transform((x1-x2, 0))
    minx, maxx = ax1.get_xlim()
    ax2.set_xlim(minx+dx, maxx+dx)  

def unrealized_profit_loss_graph(profit_loss):
    plt.style.use('ggplot');
    fig = plt.figure()
    ax1 = fig.add_subplot(111);                            
    ax2 = ax1.twiny() 
    profit_loss['total_G/l']. 
    plot(kind='barh',color=profit_loss.positive.map({True: 'g', False: 'r'}))  
    profit_loss['gain_loss_perc'].plot(kind='barh',color=profit_loss.positive.map({True: 'b', False: 'y'}))
    ax1.set_xlabel('%', fontsize=12)
    ax2.set_xlabel('$', fontsize=12);
    align_xaxis(ax1,0,ax2,0)
    plt.xlim(-5000, 20000)                              
    plt.xticks(rotation=45);
    plt.show();

I would like both x axes to align at 0. Also to show the negative plus the positive of the ax1.

Working example :

def unrealized_profit_loss():
    Profit_loss = Path("C:/Users/champ/Documents/Pers/Python/stock_dfs/Profit_loss_tranactions.xlsx")
    df = pd.read_excel(Profit_loss, sheet_name='Unrealized')
    current_prices_ROTH=price_data_ROTH.loc[price_data_ROTH.index[-1]]   current_prices_Personal=price_data_Personal.loc[price_data_Personal.index[-1]]
    df2 = pd.DataFrame({'Symbol':current_prices_ROTH.index, 'Prices':current_prices_ROTH.values})
    df2 = pd.DataFrame({'Symbol':current_prices_Personal.index, 'Prices':current_prices_Personal.values})
    da= pd.merge(df,df2, how='left',on=['Symbol','Symbol'])
    da['gain_loss_perc']=round(((da['Prices']-da['Cost/share'])/da['Cost/share'])*100,2)
    da['total_G/l']=round((da['Prices']*da['Quantity'])-(da['Cost Basis']),0)
    da['Account_symbol'] = str(da['Account'])
    da['Account_symbol'] = da.agg(lambda x: f"{x['Symbol']} - {x['Account']}", axis=1)
    da = da.sort_values(by=['total_G/l'],ascending=True)
    da.index = da['Account_symbol']
    da['positive'] = da['total_G/l'] > 0
    del da.index.name
    return(da)
def unrealized_profit_loss_graph(profit_loss):
    # graph the profit and loss                             
    #fig, (ax1,ax2) = plt.subplots(1,2,sharex=False,sharey=True,figsize=(16,8));
    #fig, ax1 = plt.subplots(1,1,figsize=(16,8));
    plt.style.use('ggplot');
    fig = plt.figure()
    ax1 = fig.add_subplot(111);
    ax1.set_title('Total G/L (UNREALIZED - IN THE MARKET)');
    #ax1 = fig.add_subplot() # Create matplotlib axes                             
    ax2 = ax1.twiny()
    profit_loss['total_G/l'].plot(kind='barh',color=profit_loss.positive.map({True: 'g', False: 'r'}))  
    profit_loss['gain_loss_perc'].plot(kind='barh',color=profit_loss.positive.map({True: 'b', False: 'y'}))
    ax1.set_xlabel('%', fontsize=12);
    ax2.set_xlabel('$', fontsize=12);                            
    plt.xlim(-5000, 20000);
    plt.xticks(rotation=45);
    align_xaxis(ax1,0,ax2,0);
    plt.show();

# Profit and loss
profit_loss = unrealized_profit_loss()
p_l = unrealized_profit_loss_graph(profit_loss)

xls file I read from

Paul
  • 113
  • 5
  • 20

1 Answers1

0

You failed to provide a working example. Nevertheless, try the following: Pass the respective axis to the plot function and then try aligning

def unrealized_profit_loss_graph(profit_loss):
    plt.style.use('ggplot')
    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    profit_loss['total_G/l'].plot(kind='barh',
                                  color=profit_loss.positive.map({True: 'g', False: 'r'}), 
                                  ax=ax1)  
    ax2 = ax1.twiny()
    profit_loss['gain_loss_perc'].plot(kind='barh',
                                       color=profit_loss.positive.map({True: 'b', False: 'y'}), 
                                       ax=ax2)

    ax1.set_xlabel('%', fontsize=12)
    ax2.set_xlabel('$', fontsize=12)
    plt.xlim(-5000, 20000)                              
    plt.xticks(rotation=45)
    align_xaxis(ax1,0,ax2,0)
    plt.show();
Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • Hopefully this is a working example. It still doesn't work. The x-axes are still not aligned at 0. – Paul Jul 28 '19 at 20:06