3

How should I align the text labels against the x tickers in the graph here ? I am using host.set_xticklabels(labels,rotation='vertical') , but that doesnt seem to work . My labels are sentences and some could be smaller/larger than others, like "The mummy returns part 2" - How do I pad a space below the x axis to accommodate this ?

enter image description here

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

path='/home/project/df.csv'
df=pd.read_csv(path,sep=',',header='infer')
xs =range(0,101)
ys =list(df['B'].ix[0:100])
zs=list(df['C'].ix[0:100])
ws=list(df['D'].ix[0:100])

if 1:
    host = host_subplot(111, axes_class=AA.Axes)
    p1, = host.plot(xs, ys, label='B')
    plt.subplots_adjust(right=0.75)

    par1 = host.twinx()
    par2 = host.twinx()

    offset = 60
    new_fixed_axis = par2.get_grid_helper().new_fixed_axis
    par2.axis["right"] = new_fixed_axis(loc="right",
                                        axes=par2,
                                        offset=(offset, 0))

    par2.axis["right"].toggle(all=True)
    host.set_xlim(min(xs), max(xs))
    host.set_ylim(100, max(ys))

    host.set_xlabel("A")
    host.set_ylabel("B")
    par1.set_ylabel("C")
    par2.set_ylabel("D")

    p2, = par1.plot(xs, ws, label='C',color='red')
    p3, = par2.plot(xs, zs, label='D',color='green')
    for tl in par1.get_yticklabels():
        tl.set_color('red')
    for tl in par2.get_yticklabels():
        tl.set_color('green')



    for tl in par1.get_yticklabels():
        tl.set_color('r')
    for tl in par2.get_yticklabels():
        tl.set_color('g')
    host.legend()

    host.axis["left"].label.set_color(p1.get_color())
    par1.axis["right"].label.set_color(p2.get_color())
    par2.axis["right"].label.set_color(p3.get_color())
    start, end, stepsize=0,len(df)-1,3
    host.xaxis.set_ticks(np.arange(start, end, stepsize))
    labels=list(df['A'])[0::stepsize]
    host.set_xticklabels(labels,rotation='vertical')
    plt.tight_layout()
    plt.draw()
    plt.show()

I need to align the "black" mass as in the picture.

I tried the suggestions in the example here python rotate values on xaxis to not overlap - plt.xticks(x, labels, rotation='vertical') , and more, but that did not work.

Edit -: From Kazemakaze's feedback below, here's what I tried -: f,host= plt.subplots() #host = host_subplot(111, axes_class=AA.Axes) but I must adapt the rest of the code as well . Can you provide an example with twinx axis where this works ?

I am adapting my code to this Secondary axis with twinx(): how to add to legend? and the rotation works now, need some pointers on the secondary axis though.

Community
  • 1
  • 1
ekta
  • 1,560
  • 3
  • 28
  • 57
  • It's hard to see in your picture - do the labels fail to rotate correctly? – MB-F Feb 02 '15 at 10:42
  • Well when I plot them say labels[0:10] - I see all of them in a straight line, no matter what the rotation - can you try this with a random sample data. I can give you a post a text of labels in edit. – ekta Feb 02 '15 at 10:48
  • Try with sample labels - ["the mummy returns","lila", "ringa ringa roses", "what a beautiful day"]*10 [or whatever you number of records in random data be] – ekta Feb 02 '15 at 10:50
  • 1
    I can reproduce your problem. It seems the rotation does not work with `host_subplot`. It works correctly when using `plt.subplot`instead. – MB-F Feb 02 '15 at 11:00
  • @kazemakase Please be a bit more specific, or I can test and then accept it. Also added my edit as comments, above – ekta Feb 02 '15 at 11:14
  • sorry, I don't know how twin axes work. Maybe someone else can help out there. – MB-F Feb 02 '15 at 12:10

1 Answers1

3

Here's how I solved it- the problem of not rotating was indeed with host_subplot and it works correctly when using plt.subplot

enter image description here

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

path='/home/project/df.csv'
df=pd.read_csv(path,sep=',',header='infer')
xs =range(0,101)
ys =list(df['B'].ix[0:100])
zs=list(df['C'].ix[0:100])
ws=list(df['D'].ix[0:100])


def make_patch_spines_invisible(ax):
    ax.set_frame_on(True)
    ax.patch.set_visible(False)
    for sp in ax.spines.itervalues():
        sp.set_visible(False)


def three_way_plot(xs,ys,ws,zs,category):
    fig, host = plt.subplots()
    fig.subplots_adjust(right=0.6)
    par1 = host.twinx()
    par2 = host.twinx()
    par2.spines["right"].set_position(("axes", 1.1))
    p1, = host.plot(xs, ys, "blue", linewidth=2.0, label="B")
    p2, = par1.plot(xs, ws, "r-", label="C")
    p3, = par2.plot(xs, zs, "g-", label="D")
    host.set_xlim(min(xs), max(xs))
    host.set_ylim(min(ys), max(ys) + 200)
    par1.set_ylim(min(ws), max(ws) + 200)
    par2.set_ylim(min(zs), max(zs))
    host.set_xlabel("A", fontsize=14)
    host.set_ylabel("B", fontsize=14)
    par1.set_ylabel("C", fontsize=14)
    par2.set_ylabel("D", fontsize=14)
    host.yaxis.label.set_color(p1.get_color())
    par1.yaxis.label.set_color(p2.get_color())
    par2.yaxis.label.set_color(p3.get_color())
    lines = [p1, p2, p3]
    labels = ["mary had a little lamb","The mummy returns","Die another day","Welcome back"]*25
    start, end, step_size = 0, len(df) - 1, 4
    host.set_xticks(np.arange(start, end, step_size))
    host.set_xticklabels(labels, rotation='vertical', fontsize=10)
    host.legend(lines, [l.get_label() for l in lines])
    plt.tight_layout()
    plt.show()


three_way_plot(xs,ys,ws,zs,"category")

Ofcourse, I masked the True labels of the data.

ekta
  • 1,560
  • 3
  • 28
  • 57