pythonmatplotliblinesequence-alignment

Draw lines connecting points between two separate one-D plots


As title, I am working on time-series alignment, and a visualization of the alignment result is desired.

To this end, I want to draw lines connecting "anchor points" generated by the alignment algorithm.

np.random.seed(5)
x = np.random.rand(10)      # time-series 1
y = np.random.rand(20)      # time-series 2
ap = np.array(([0, 4,  9],  # the anchor points
               [0, 9, 19]))

fig = plt.figure(figsize=(10,5))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
ax1.plot(x, 'r')
ax2.plot(y, 'g')

the anchor points ap in the example specify the one-to-one "mapping" between the indices of two time series x and y, i.e., x[0] is corresponding to y[0]; x[4] to y[9]; and x[9] to y[19]. The goal is to draw lines between two separate plot to show the result of the alignment.


Solution

  • To connect two subplots in matplotlib you may use a ConnectionPatch.

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.patches import ConnectionPatch
    
    np.random.seed(5)
    x = np.random.rand(21)      # time-series 1
    y = np.random.rand(21)      # time-series 2
    ap = np.array(([0, 5, 10],  # the anchor points
                   [0,10, 20]))
    
    fig = plt.figure(figsize=(10,5))
    ax1 = fig.add_subplot(211)
    ax2 = fig.add_subplot(212)
    ax1.plot(x, 'r')
    ax2.plot(y, 'g')
    
    ls = ["-","--"]
    c = ["gold", "blue"]
    
    for i, row in enumerate(ap):
        for j, ind in enumerate(row):
            px = (ind, x[ind])
            py = (ind, y[ind])
            con = ConnectionPatch(py,px, coordsA="data", coordsB="data",
                          axesA=ax2, axesB=ax1, linestyle=ls[i], color=c[i])
            ax2.add_artist(con)
    
    plt.show()
    

    enter image description here