JadeChee JadeChee - 1 month ago 11
Python Question

Break x axis in more than 2 parts (Python)

I'm trying to break up my x axis in 5 parts. There exists many answers on how to break it up in 2 parts, so I've followed the same strategy but it doesn't work for more than 2 parts.
Has anyone ever succeeded breaking up an axis in more than 2 parts?

import numpy as np
from pylab import *
import matplotlib.pyplot as plt

fig,(ax,ax2,ax3,ax4,ax5) = plt.subplots(1,2,sharey=True)
ax.plot(wvln0,alb0,linestyle='-', marker='o', color='r',linewidth=1.0,label='Haze = 0T')
ax2.plot(wvln0,alb0,linestyle='-', marker='o', color='r',linewidth=1.0,label='Haze = 0T')
ax3.plot(wvln0,alb0,linestyle='-', marker='o', color='r',linewidth=1.0,label='Haze = 0T')
ax4.plot(wvln0,alb0,linestyle='-', marker='o', color='r',linewidth=1.0,label='Haze = 0T')
ax5.plot(wvln0,alb0,linestyle='-', marker='o', color='r',linewidth=1.0,label='Haze = 0T')
ax.set_xlim(0.15,1.10)
ax2.set_xlim(1.15,2.25)
ax3.set_xlim(1.20,1.30)
ax4.set_xlim(1.55,1.65)
ax5.set_xlim(1.95,2.15)

ax.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax.yaxis.tick_left()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.yaxis.tick_right()
plt.subplots_adjust(wspace=0.1)

axes = plt.gca()
axes.set_ylim([0.0,0.72])
plt.show()


Returns

Traceback (most recent call last):
File "/Users/jadecheclair/Documents/NASA Ames Research/NASA Codes/Wavlengths_Rages/wvln_alb.py", line 37, in <module>
fig,(ax,ax2,ax3,ax4,ax5) = plt.subplots(1,2,sharey=True)
ValueError: need more than 2 values to unpack


And if I try to change the line to

fig,(ax,ax2,ax3,ax4,ax5) = plt.subplots(1,2,3,4,5,sharey=True)


It returns

Traceback (most recent call last):
File "/Users/jadecheclair/Documents/NASA Ames Research/NASA Codes/Wavlengths_Rages/wvln_alb.py", line 37, in <module>
fig,(ax,ax2,ax3,ax4,ax5) = plt.subplots(1,2,3,4,5,sharey=True)
TypeError: subplots() got multiple values for keyword argument 'sharey'

Answer

This is a example showing how I've done it by placing three axes manually in a figure.

from __future__ import division, unicode_literals
import matplotlib.pyplot as plt
import numpy as np

plt.close('all')

# ----- PREPARE DATA ----

t = np.arange(0, 7 * 10**5, 10)
x = np.abs(np.sin(t/10.**2)) * 300

# ----- FIG CREATION ----

fig = plt.figure(figsize=(8, 5), facecolor='white')

# Margins (dimensions are in inches):
left_margin = 0.6 / fig.get_figwidth()
right_margin = 0.25 / fig.get_figwidth()
bottom_margin = 0.75 / fig.get_figheight()
top_margin = 0.25 / fig.get_figwidth()
mid_margin = 0.1 / fig.get_figwidth()  # horizontal space between subplots

# ----- DEFINE PARAMETERS FOR EACH AXE ----

# Proportion of the figure's width taken by each axe (the sum must == 1):
f = [0.5, 0.3, 0.2]

xmin = [200, 50, 0]     # xaxis minimum values for each axe
xmax = [8200, 200, 50]  # xaxis maximum values for each axe
xscl = [2000, 50, 10]   # xaxis scale for each axe

ymin, ymax = 0, 320  # yaxis minimum and maximum values

colors = ['green', 'blue', 'red']  # colors of each plot
labels = ['label1', 'label2', 'label3']  # labels of each plot for the legend

Naxes = len(f)  # Total number of axes to add to the figure.

x0, y0 = left_margin, bottom_margin   # origin point of the axe
h = 1 - (bottom_margin + top_margin)  # height of the axe

# total width of the axes:
wtot = 1 - (left_margin + right_margin + (Naxes-1)*mid_margin)

lines = []  # to store handles for generating the legend later on
for i in range(Naxes):

    # ----- AXES CREATION ----

    w = wtot*f[i]  # width of the current axe
    ax = fig.add_axes([x0, y0, w, h], frameon=True, axisbg='none')

    if i == 0:  # First axe to the left
        ax.spines['right'].set_visible(False)
        ax.tick_params(right='off', labelright='off')

    elif i == Naxes-1:  # Last axe to the right
        ax.spines['left'].set_visible(False)
        ax.tick_params(left='off', labelleft='off',
                       right='off', labelright='off')
    else:
        ax.spines['left'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.tick_params(left='off', labelleft='off',
                       right='off', labelright='off')

    # origin point of the next axe to be added to the figure:
    x0 += w + mid_margin

    # ----- SETUP XTICKS ----

    if i == Naxes-1:
        xticks = np.arange(xmin[i], xmax[i] + xscl[i]/2, xscl[i])
    else:
        xticks = np.arange(xmin[i]+xscl[i], xmax[i] + xscl[i]/2, xscl[i])
    ax.set_xticks(xticks)
    ax.xaxis.set_ticks_position('bottom')
    ax.tick_params(axis='x', direction='out', labelsize=8)

    xticks_minor = np.arange(xmin[i], xmax[i] + xscl[i]/5., xscl[i] / 5.)
    ax.set_xticks(xticks_minor, minor=True)
    ax.tick_params(axis='x', which='minor', direction='out')

    # ----- PLOT DATA ----

    line, = ax.plot(t, x, color=colors[i])
    lines.append(line)  # for plotting the legend

    ax.axis([xmin[i], xmax[i], ymin, ymax])
    ax.invert_xaxis()

# ---- SET XAXIS LABEL ----

fig.axes[0].set_xlabel('Time (years)', fontsize=12, va='bottom', ha='center')
fig.axes[0].xaxis.set_label_coords(0.5, 0.05, transform=fig.transFigure)

# -----  LEGEND ----

fig.axes[0].legend(lines, labels, loc=(0.1, 0.1), ncol=1, fancybox=True,
                   fontsize=12)

# ----- SHOW FIG ----

fig.savefig('SingleAxeThreeScale.png')
plt.show()

Which results in:

enter image description here

Comments