Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple lines of x tick labels in matplotlib

Tags:

I'm trying to make a plot similar to this excel example:

example

I would like to know if there is anyways to have a second layer on the x tick labels (e.g. "5 Year Statistical Summary"). I know I can make multi-line tick labels using \n but I want to be able to shift the two levels independently.

like image 551
HHains Avatar asked Dec 12 '13 00:12

HHains


People also ask

How do I create a multi X-axis in MatPlotLib?

We can use the twiny() method to create a second X-axis. Similarly, using twinx, we can create a shared Y-axis.

How do I plot multiple lines in MatPlotLib?

Import matplotlib. To create subplot, use subplots() function. Next, define data coordinates using range() function to get multiple lines with different lengths. To plot a line chart, use the plot() function.

How do I show all X labels in MatPlotLib?

MatPlotLib with Python To show all X coordinates (or Y coordinates), we can use xticks() method (or yticks()).

How do you avoid overlapping X-axis labels in MatPlotLib?

Matplotlib x-axis label overlap In matplotlib, we have a method setp() that is used to set the rotation and alignment attributes of tick labels to avoid overlapping. To get ticklabels, we use the plt. setp() and get.


2 Answers

this gets close:

xtick

fig = plt.figure( figsize=(8, 4 ) ) ax = fig.add_axes( [.05, .1, .9, .85 ] ) ax.set_yticks( np.linspace(0, 200, 11 ) )  xticks = [ 2, 3, 4, 6, 8, 10 ] xticks_minor = [ 1, 5, 7, 9, 11 ] xlbls = [ 'background', '5 year statistical summary', 'future build',           'maximum day', '90th percentile day', 'average day' ]  ax.set_xticks( xticks ) ax.set_xticks( xticks_minor, minor=True ) ax.set_xticklabels( xlbls ) ax.set_xlim( 1, 11 )  ax.grid( 'off', axis='x' ) ax.grid( 'off', axis='x', which='minor' )  # vertical alignment of xtick labels va = [ 0, -.05, 0, -.05, -.05, -.05 ] for t, y in zip( ax.get_xticklabels( ), va ):     t.set_y( y )  ax.tick_params( axis='x', which='minor', direction='out', length=30 ) ax.tick_params( axis='x', which='major', bottom='off', top='off' ) 
like image 96
behzad.nouri Avatar answered Oct 18 '22 20:10

behzad.nouri


I'm unable to comment on behzad's answer due to lack of reputation. I found his solution to be immensely helpful, but I thought I'd share that instead of controlling the vertical alignment by using set_y(), I just added a newline character to vertically offset the labels. So, for the above example:

xlbls = [ 'background', '\n5 year statistical summary', 'future build',       '\nmaximum day', '\n90th percentile day', '\naverage day' ] 

For me, this was a better solution for keeping multi-lined labels and multi-layered labels vertically aligned.

like image 38
omegamanda Avatar answered Oct 18 '22 18:10

omegamanda