pythonmatplotlibplot

Plotting a second scaled y axis in matplotlib from one set of data


I have two views of the same data, which calls for the need to have another y-axis which is scaled appropriately from the first natural y-axis. So when I plot my {x,y} data, the left y-axis shows y, but the right y-axis also shows 1/y or any other function. I do not ever want to plot {x, f(x)} or {x, 1/y}.

Now to complicate matters I am using the .plt style of interaction rather than the axis method.

plt.scatter(X, Y, c=colours[count], alpha=1.0, label=chart, lw = 0)
plt.ylabel(y_lbl)
plt.xlabel(x_lbl)

Is there another way - with plt? Or is it a case of generating two overlain plots and changing the alpha appropriately?


Solution

  • I had to check your previous (duplicate) question and all the comments to understand what you actually want. So to just get a secondary y-axis you can still use twinx. Then you can use set_ylim make sure it has the same limits as the first. To put tick labels according to some function (in your case 1/y) you can use a custom FuncFormatter.

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.ticker as mticker
    
    fig, ax1 = plt.subplots(1,1)
    ax1.set_xlabel('x')
    ax1.set_ylabel('y')
    
    # plot something
    x = np.linspace(0.01, 10*np.pi, 1000)
    y = np.sin(x)/x
    ax1.plot(x, y)
    
    # add a twin axes and set its limits so it matches the first
    ax2 = ax1.twinx()
    ax2.set_ylabel('1/y')
    ax2.set_ylim(ax1.get_ylim())
    
    # apply a function formatter
    formatter = mticker.FuncFormatter(lambda x, pos: '{:.3f}'.format(1./x))
    ax2.yaxis.set_major_formatter(formatter)
    
    plt.show()
    

    Result: enter image description here