0

Basically, I want to stack 3 graphs on top of each other so that they can share the x. The problem is, is that some of the plots use the twinx command(?) because they have 2 or more y axes.

If it's not clear what I mean, I have manually put the graphs together to see how it looks but it's not as nice. (NB/ ignore the lines down the graph and I'd also like no x labels on 1 or 2)

Example of graphs

Additionally, an example of one of the figures code is shown below - if it helps at all.

fig = plt.figure()
ax = plt.subplot2grid((2, 2), (0, 0), rowspan=2, colspan=2)
fig.subplots_adjust(left=0.13, bottom=0.12, right=0.91, top=0.9, wspace=0.3, 
hspace=0.5)
plt.margins(x=0)

ax.scatter(data['elapsed_seconds'], Abut_Stress, label='Abutment Stress 
Calculated', linewidth=0, marker='o', s=20,
       c='k')

ax.plot(data['elapsed_seconds'], data['wheel_temp_c'], label='Wheel 
Temperature', linestyle="-", color='b')
ax.plot(data['elapsed_seconds'], data['abut_temp_c'], label='Abutment 
Temperature', linestyle="-", color='g')
ax2 = ax.twinx()
ax2.plot(data['elapsed_seconds'], data['wheel_speed'], label='Wheel Speed', 
linestyle="-", color='r')

# -------------Get legend names to be plotted in the same legend box-------

h1, l1 = ax.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
lg = ax.legend(h1 + h2, l1 + l2, bbox_to_anchor=(0., 0.8, 1., .102), loc=3, 
ncol=1, borderaxespad=0., fontsize=28, )
lg.get_frame().set_linewidth(0.5)

# ----------------------Settings for the first figure window---------------

ax.set_ylim(0, 1000)
ax2.set_ylim(0, 12)
ax.set_xlim(0,data_end)
ax.set_xlabel(r"Time (s)")
ax.set_ylabel(r"Abutment Stress (MPa)    Temperature($^\circ$C)")
ax2.set_ylabel(r"Wheel Speed (RPM)")

ax.get_xaxis().tick_bottom()  
ax2.get_xaxis().tick_bottom()
DavidG
  • 24,279
  • 14
  • 89
  • 82

1 Answers1

0

Here's a simple script to do what you want. It uses plt.subplots to create the first three Axes with a shared xaxis, then ax.twinx to create the twin Axes.

The offset spine on one of the shared axes is done using this example on the matplotlib gallery.

import matplotlib.pyplot as plt

def make_patch_spines_invisible(ax, offset):
    '''
    This function inspired by this example, to offset a twin axis spine. 
    link: https://matplotlib.org/gallery/ticks_and_spines/multiple_yaxis_with_spines.html
    '''
    ax.spines["right"].set_position(("axes", offset))
    ax.set_frame_on(True)
    ax.patch.set_visible(False)
    for sp in ax.spines.values():
        sp.set_visible(False)
    ax.spines["right"].set_visible(True)

# First create your figure, with 3 subplots sharing the x axis.
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, sharex=True)

# make some room on the right for the twin axes
fig.subplots_adjust(right=0.8)

# The easy ones, create the first twin axes on ax1 and ax2
ax1t = ax1.twinx()
ax2t = ax2.twinx()

# Create the twin axis on ax2 with an offset spine
ax2tb = ax2.twinx()
make_patch_spines_invisible(ax2tb, offset=1.15)

# Here I just set some axes limits to show the y axis scales are all independent
ax3.set_xlim(0, 900)

ax1.set_ylim(0, 2000)
ax2.set_ylim(0, 1000)
ax3.set_ylim(0, 50)

ax1t.set_ylim(0, 12)
ax2t.set_ylim(0, 12)
ax2tb.set_ylim(0, 100)

plt.show()

enter image description here

tmdavison
  • 64,360
  • 12
  • 187
  • 165
  • What happens with regards to independent legends? Do I just add those directly to the plot as before? – Sarah A Smythe Apr 20 '18 at 12:12
  • See here for some examples of wither adding separate legends, or combining legends: https://stackoverflow.com/questions/5484922/secondary-axis-with-twinx-how-to-add-to-legend – tmdavison Apr 20 '18 at 15:27