31

I have tried the following:

d = [1,2,3,4,5,6,7,8,9]
f = [0,1,0,0,1,0,1,1,0]
fig = plt.figure()
fig.set_size_inches(30,10)
ax1 = fig.add_subplot(211)
line1 = ax1.plot(d,marker='.',color='b',label="1 row")
ax2 = fig.add_subplot(212)
line1 = ax2.plot(f,marker='.',color='b',label="1 row")
ax1.grid()
ax2.grid()
plt.show()

I got the following output :

output

But I was expecting the following output:
expected output

How I can get the grids across the two plots?

7
  • Possible duplicate of Draw line between two subplots Commented Aug 30, 2018 at 11:07
  • @SpghttCd That is for matlab. This question asks for Python Commented Aug 30, 2018 at 11:09
  • Sorry, I know there was this question for matplotlib in the last few months, so I was too fast on choosing. Commented Aug 30, 2018 at 11:12
  • Possible duplicate of Plotting a line over several graphs Commented Aug 30, 2018 at 11:12
  • This link here might help. Although it is not gridlines exactly but you can turn them black and thin to make them look like one Commented Aug 30, 2018 at 11:13

4 Answers 4

34

There is no built-in option to create inter-subplot grids. In this case I'd say an easy option is to create a third axes in the background with the same grid in x direction, such that the gridline can be seen in between the two subplots.

import matplotlib.pyplot as plt

d = [1,2,3,4,5,6,7,8,9]
f = [0,1,0,0,1,0,1,1,0]

fig, (ax1,ax2) = plt.subplots(nrows=2, sharex=True)
ax3 = fig.add_subplot(111, zorder=-1)
for _, spine in ax3.spines.items():
    spine.set_visible(False)
ax3.tick_params(labelleft=False, labelbottom=False, left=False, right=False )
ax3.get_shared_x_axes().join(ax3,ax1)
ax3.grid(axis="x")


line1 = ax1.plot(d, marker='.', color='b', label="1 row")
line1 = ax2.plot(f, marker='.', color='b', label="1 row")
ax1.grid()
ax2.grid()
plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Its a great share.. Let me try it out.
5

Here is my solution:

import matplotlib.pyplot as plt

x1 = [1,2,3,4,5,6,7,8,9]
x2= [0,1,0,0,1,0,1,1,0]
x3= range(-10,0)
# frameon=False removes frames
# fig, (ax1,ax2, ax3) = plt.subplots(nrows=3, sharex=True, subplot_kw=dict(frameon=False))
fig, (ax1,ax2, ax3) = plt.subplots(nrows=3, sharex=True)
# remove vertical gap between subplots
plt.subplots_adjust(hspace=.0)

ax1.grid()
ax2.grid()
ax3.grid()

ax1.plot(x1)
ax2.plot(x2)
ax3.plot(x3)

enter image description here

Without frames subplot_kw=dict(frameon=False):

enter image description here

Comments

2

An option is to create a single plot then just offset the data. So one set plots above the other.

1 Comment

Thank you for your reply. Please can you give an example as you see I have given the data that I am trying to plot. Your answer looks like comment but since you have less score so you are unable to comment. If you give an example then it will be more helpful to everybody.
1

Solution

You can extend the grid lines by passing the appropriate coordinates through to Line2D with ax1.grid(ydata=[-space_between_axes, 1], clip_on=False).

import matplotlib.pyplot as plt

d = [1,2,3,4,5,6,7,8,9]
f = [0,1,0,0,1,0,1,1,0]
fig = plt.figure()
fig.set_size_inches(30,10)
ax1 = fig.add_subplot(211)
line1 = ax1.plot(d,marker='.',color='b',label="1 row")
ax2 = fig.add_subplot(212)
line1 = ax2.plot(f,marker='.',color='b',label="1 row")
plt.setp(ax1.get_xticklabels(), backgroundcolor="white")  # Eliminate strike-through.
space_between_plots = plt.rcParams["figure.subplot.hspace"]  # <==========
ax1.xaxis.grid(ydata=[-space_between_plots, 1], clip_on=False)  # <==========
ax1.yaxis.grid()
ax2.grid()
plt.show()

enter image description here

How does this work?

  • Per the docs of the matplotlib.axis.Axis.grid == ax1.xaxis.grid method, keyword arguments can be passed on to Line2D.
  • Line2D takes the x- and y-coordinates (xdata and ydata) as arguments.
  • But what coordinate system is used? You can check this with ax1.get_xgridlines()[-1].get_xydata(). The output is array([[9., 0.], [9., 1.]]). Apparently the x-values are in Data coordinates and the y-values are in Axes coordinates.
  • Next question: How far down do you need to extend? In this particular case you can just take the number -1 because the overlap with the same lines further down is invisible. The proper way however is to get the actual distance, in this case with space_between_plots = plt.rcParams["figure.subplot.hspace"]. That's 0.2 which means one fifth of the height of one plot.
  • The top stays the same at 1.
  • clip_on=True is needed because Matplotlib doesn't draw anything outside the plotting area by default.

Note

It looks like Matplotlib has a bug that makes this solution unworkable in some circumstances. E.g. if I leave out plt.setp(...), Maptlotlib complains that it receives the ydata argument multiple times and raises a TypeError.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.