Search code examples
pythonmatplotlibdiagram

Python matplotlib: connect two subplot diagrams


I try to create a diagramm with a broken x-axis. I used the example which can be found at the matplotlib page.

The problem for me is: how can I connect both diagrams? I need a closed line for the graph (and both x-axis should be come more close).

Is there a way to get this?

import matplotlib.pyplot as plt

#x-axis
x_axis = [0,1,2,3,4,5,6,7,8,19,20,21,22,23,24,25]

# Line 1
line = [99,91,86,80,80,76,72,72,73,74,76,78,79,80,80,80]


# create broken x-axis
f, (ax, ax2) = plt.subplots(1, 2, sharey=True)
ax.step(x_axis, line, color='red')
ax2.step(x_axis, line, color='red')

ax.set_xlim(0, 10.5)
ax2.set_xlim(18.5, 30)

ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

ax2.spines['left'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)

ax2.tick_params(
                axis='y',
                which='both',
                left='off')

# seperators for x-axis

d = .015
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) 

kwargs.update(transform=ax2.transAxes) 
ax2.plot ( (0-d ,0+d),(-d, +d ), **kwargs)

plt.show()

Is there a way to get "one" diagram?

Current diagramm of 2 subplots (png)


Solution

  • You can use the lines on your figure object. The advantage is that these figure lines are of higher level that the ones on axis, so no need to worry about drawing axis for it. (I got the idea from this stackoverflow answer: ref)

    Applied to your code, this look like this:

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    #x-axis
    x_axis = [0,1,2,3,4,5,6,7,8,19,20,21,22,23,24,25]
    
    # Line 1
    line = [99,91,86,80,80,76,72,72,73,74,76,78,79,80,80,80]
    
    
    # create broken x-axis
    f, (ax, ax2) = plt.subplots(1, 2, sharey=True)
    ax.step(x_axis, line, color='red')
    ax2.step(x_axis, line, color='red')
    
    ax.set_xlim(0, 10.5)
    ax2.set_xlim(18.5, 30)
    
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    
    ax2.spines['left'].set_visible(False)
    ax2.spines['top'].set_visible(False)
    ax2.spines['right'].set_visible(False)
    
    ax2.tick_params(
                    axis='y',
                    which='both',
                    left='off')
    
    # seperators for x-axis
    
    d = .015
    kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
    ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) 
    
    kwargs.update(transform=ax2.transAxes) 
    ax2.plot ( (0-d ,0+d),(-d, +d ), **kwargs)
    
    # transFigure: used to transform the coordinates from your subplots
    # to coordinates on the figure
    # points are hardcoded as an example
    transFigure = f.transFigure.inverted()
    # last point on your left figure
    coord1 = transFigure.transform(ax.transData.transform([8,74]))
    # first point on your right figure
    coord2 = transFigure.transform(ax2.transData.transform([19,74]))
    
    # generate your line with the transformed coordinates
    line = mpl.lines.Line2D((coord1[0],coord2[0]),(coord1[1],coord2[1]),
                           transform=f.transFigure, color='red')
    # add your line to the figure
    f.lines.append(line)
    
    plt.show()
    

    enter image description here