I'm a Matlab user recently converted to Python. Most of the Python skills I manage on my own, but with plotting I have hit the wall and need some help.
This is what I'm trying to do...
I need to make a figure that consists of 3 subplots with following properties:
By the way I know how to make all this, only not in a single figure. That is the problem I'm facing now.
For example, this is my ideal subplot layout:
import numpy as np import matplotlib.pyplot as plt  t = np.arange(0.0, 2.0, 0.01)  s1 = np.sin(2*np.pi*t) s2 = np.exp(-t) s3 = s1*s2  fig = plt.figure() ax1 = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2) ax2 = plt.subplot2grid((4,3), (2,0), colspan=3) ax3 = plt.subplot2grid((4,3), (3,0), colspan=3)  ax1.plot(t,s1) ax2.plot(t[:150],s2[:150]) ax3.plot(t[30:],s3[30:])  plt.tight_layout()  plt.show()   Notice how the x axis of different subplots is misaligned. I do not know how to align the x axis in this figure, but if I do something like this:
import numpy as np import matplotlib.pyplot as plt  t = np.arange(0.0, 2.0, 0.01)  s1 = np.sin(2*np.pi*t) s2 = np.exp(-t) s3 = s1*s2  fig2, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, sharex=True)  ax1.plot(t,s1) ax2.plot(t[:150],s2[:150]) ax3.plot(t[30:],s3[30:])  plt.tight_layout()  plt.show()   Now the x axis is aligned between the subplots, but all subplots are the same size (which is not what I want)
Furthermore, I would like that the subplots are touching at x axis like this:
import numpy as np import matplotlib.pyplot as plt  t = np.arange(0.0, 2.0, 0.01)  s1 = np.sin(2*np.pi*t) s2 = np.exp(-t) s3 = s1*s2  fig1 = plt.figure() plt.subplots_adjust(hspace=0)  ax1 = plt.subplot(311) ax2 = plt.subplot(312, sharex=ax1) ax3 = plt.subplot(313, sharex=ax1)  ax1.plot(t,s1) ax2.plot(t[:150],s2[:150]) ax3.plot(t[30:],s3[30:])  xticklabels = ax1.get_xticklabels()+ax2.get_xticklabels() plt.setp(xticklabels, visible=False)  plt.show()   So to rephrase my question:
I would like to use
plt.subplot2grid(..., colspan=3, rowspan=2) plt.subplots(..., sharex=True) plt.subplots_adjust(hspace=0)   and
plt.tight_layout()   together in the same figure. How to do that?
If sharex is set to False or none , each x-axis of a subplot will be independent. If it is set to row , each subplot row will share an x-axis. If it is set to col , each subplot column will share an x-axis. sharey.
You can share the x or y axis limits for one axis with another by passing an Axes instance as a sharex or sharey keyword argument.
Controls sharing of properties among x ( sharex ) or y ( sharey ) axes: True or 'all': x- or y-axis will be shared among all subplots. False or 'none': each subplot x- or y-axis will be independent. 'row': each subplot row will share an x- or y-axis.
To remove the space between subplots in matplotlib, we can use GridSpec(3, 3) class and add axes as a subplot arrangement.
Just specify sharex=ax1 when creating your second and third subplots.
import numpy as np import matplotlib.pyplot as plt  t = np.arange(0.0, 2.0, 0.01)  s1 = np.sin(2*np.pi*t) s2 = np.exp(-t) s3 = s1*s2  fig = plt.figure() ax1 = plt.subplot2grid((4,3), (0,0), colspan=3, rowspan=2) ax2 = plt.subplot2grid((4,3), (2,0), colspan=3, sharex=ax1) ax3 = plt.subplot2grid((4,3), (3,0), colspan=3, sharex=ax1)  ax1.plot(t,s1) ax2.plot(t[:150],s2[:150]) ax3.plot(t[30:],s3[30:])  fig.subplots_adjust(hspace=0)    for ax in [ax1, ax2]:     plt.setp(ax.get_xticklabels(), visible=False)     # The y-ticks will overlap with "hspace=0", so we'll hide the bottom tick     ax.set_yticks(ax.get_yticks()[1:])    plt.show()   
If you still what to use fig.tight_layout(), you'll need to call it before fig.subplots_adjust(hspace=0).  The reason for this is that tight_layout works by automatically calculating parameters for subplots_adjust and then calling it, so if subplots_adjust is manually called first, anything in the first call to it will be overridden by tight_layout.
E.g.
fig.tight_layout() fig.subplots_adjust(hspace=0) 
                        A possible solution is to manually create the axis using the add_axis method like shown here:
import numpy as np import matplotlib.pyplot as plt  t = np.arange(0.0, 2.0, 0.01)  s1 = np.sin(2*np.pi*t) s2 = np.exp(-t) s3 = s1*s2  left, width = 0.1, 0.8 rect1 = [left, 0.5, width, 0.4] rect2 = [left, 0.3, width, 0.15] rect3 = [left, 0.1, width, 0.15]  fig = plt.figure() ax1 = fig.add_axes(rect1)  #left, bottom, width, height ax2 = fig.add_axes(rect2, sharex=ax1) ax3  = fig.add_axes(rect3, sharex=ax1)  ax1.plot(t,s1) ax2.plot(t[:150],s2[:150]) ax3.plot(t[30:],s3[30:])  # hide labels for label1,label2 in zip(ax1.get_xticklabels(),ax2.get_xticklabels()):     label1.set_visible(False)     label2.set_visible(False)  plt.show()   But this way you cannot use tight_layout as you explicitly define the size of each axis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With