Search code examples
pythonminimization

How to match two different graphs as much as possible by reducing difference in y-axis step by step by iteration in python


I am trying to match two graphs drawn below as close as possible by shifting one graph to another one in python.

Figure

Two graphs are of different ranges in x and these are drawn from two array datasets.

What I am thinking now is that by shifting one by one iteration of one of them and let it move until the difference between two data (or graph) get minimized.

Yet, I have no idea how to start.


Solution

  • What I'd do is try to shift one of the sets such that root mean square of difference between it and the other one is minimised. You could also narrow the criterion down to a region of interest in the data (I'm guessing around the peak). To compute RMS error, you'll need to interpolate the data onto the same x-values. Here's an example:

    import numpy as np
    import matplotlib.pyplot as plt
    
    from scipy.optimize import minimize
    
    # Create data
    x0 = np.linspace(0, 2.*np.pi, 101)
    y0 = np.sin(x0)
    x1 = np.linspace(0, 2.*np.pi, 201)
    y1 = np.sin(x1+0.1*np.pi)
    
    def target(x):
        # Interpolate set 1 onto grid of set 0 while shifting it by x.
        y1interp = np.interp(x0, x1+x, y1)
    
        # Compute RMS error between the two data with set 1 shifted by x.
        return np.sqrt(np.sum((y0-y1interp)**2.))
    
    result = minimize(target, method="BFGS", x0=[0.])#, bounds=[(-0.2, 0.2)]) # bounds work with some methods only
    print(result)
    
    plt.figure()
    plt.plot(x0, y0, "r", x1, y1, "b")
    plt.plot(x1+result.x, y1, "k", lw=2)
    plt.legend(["set 0", "set 1", "set 1 shifted"])
    

    Result: enter image description here

    Note that scipy.optimize.minimize is quite sensitive to the settings so you'll need to play with them to make them better suited to tackle your problem: https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html