Search code examples
pythonmatplotlibmathsubplotmultiple-axes

How do I create a secondary axis based on on a complex conversion?


I am trying to create a secondary axis for my plot. I can get all of my lines to plot on the graph (y1 to y14) and all y values are in the same units. The conversion to a secondary unit is essentially "exp(y/7)." I struggled with this long enough to resort to chatgpt, which gave me the following after lengthy troubleshoointg:

def y_to_secondary(y):
    return  np.asarray(math.exp(np.asarray(y1)/(7)))

def secondary_to_y(secondary):
    return 7*math.log(np.asarray(secondary))

secay = ax1.secondary_yaxis('right', functions=(y_to_secondary, secondary_to_y))

I continue to get the error: TypeError: only size-1 arrays can be converted to Python scalars

I am defining my original arrays as followed:

y1=[]
T1=[]
for a in range(2,1000):
    y1.append(-7 + (2*a))

Any ideas how to fix the problem?


Solution

  • First, you don't need this np.asarray() method. You should have the following:

    def y_to_secondary(y):
        return np.exp(y/7)
    
    def secondary_to_y(secondary):
        return np.log(secondary) * 7
    

    This should fix your TypeError.

    Then I am not exactly sure what you do want to plot, but if you want a first function y1 = 2x-7 and a second y2 = exp(y/7), here is how you can do. You have to fix the x values not too high (<100), or you will encounter an overflow.

    fig, ax1 = plt.subplots()
    
    # First y-axis
    X = np.arange(2,50,1)
    y1 = 2*X-7
    plt.plot(X, y1, label='$y1$')
    ax1.plot(X, np.exp(X/7), label='$y2$')
    ax1.legend()
    
    # Second y-axis
    _ = ax1.secondary_yaxis('right', functions=(y_to_secondary, secondary_to_y))
    

    This is the result: The plot with 2 y-axis. Finally, you can play with the tick_params to better render the second y-axis.