combining a log and linear scale in matplotlib

后端 未结 3 488
时光说笑
时光说笑 2020-12-05 21:01

The example here What is the difference between 'log' and 'symlog'? nicely shows how a linear scale at the origin can be used with a log scale elsewhere. I

相关标签:
3条回答
  • 2020-12-05 21:31

    This solution makes an addition to cphlewis's answer so that there is a smooth transition, and the plot appears to have consistent tick markers. My change adds these three lines:

    axLin.spines['bottom'].set_visible(False)

    axLin.xaxis.set_ticks_position('top')

    plt.setp(axLin.get_xticklabels(), visible=False)

    In total, the code is

    # linear and log axes for the same plot?
    # starting with the histogram example from 
    # http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html
    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    import numpy as np
    
    # Numbers from -50 to 50, with 0.1 as step
    xdomain = np.arange(-50,50, 0.1)
    
    axMain = plt.subplot(111)
    axMain.plot(xdomain, np.sin(xdomain))
    axMain.set_yscale('log')
    axMain.set_ylim((0.01, 0.5))
    axMain.spines['top'].set_visible(False)
    axMain.xaxis.set_ticks_position('bottom')
    
    divider = make_axes_locatable(axMain)
    axLin = divider.append_axes("top", size=2.0, pad=0, sharex=axMain)
    axLin.plot(xdomain, np.sin(xdomain))
    axLin.set_xscale('linear')
    axLin.set_ylim((0.5, 1.5))
    
    # Removes bottom axis line
    axLin.spines['bottom'].set_visible(False)
    axLin.xaxis.set_ticks_position('top')
    plt.setp(axLin.get_xticklabels(), visible=False)
    
    plt.title('Linear above, log below')
    
    plt.show()
    

    0 讨论(0)
  • 2020-12-05 21:41

    From the response of user1318806 to cphlewis:

    Thank you. Actually I wanted a combination of log+linear on the x axis not y. But I assume your code should be easily adaptable.

    Hello! If you wanted a combination of log+linear on the x-axis (patterned from the code of Duncan Watts and CubeJockey):

    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    import numpy as np
    
    # Numbers from -50 to 50, with 0.1 as step
    xdomain = np.arange(-50,50, 0.1)
    
    axMain = plt.subplot(111)
    axMain.plot(np.sin(xdomain), xdomain)
    axMain.set_xscale('linear')
    axMain.set_xlim((0.5, 1.5))
    axMain.spines['left'].set_visible(False)
    axMain.yaxis.set_ticks_position('right')
    axMain.yaxis.set_visible(False)
    
    
    divider = make_axes_locatable(axMain)
    axLin = divider.append_axes("left", size=2.0, pad=0, sharey=axMain)
    axLin.set_xscale('log')
    axLin.set_xlim((0.01, 0.5))
    axLin.plot(np.sin(xdomain), xdomain)
    axLin.spines['right'].set_visible(False)
    axLin.yaxis.set_ticks_position('left')
    plt.setp(axLin.get_xticklabels(), visible=True)
    
    plt.title('Linear right, log left')
    

    The code above yields: Answer1

    (MISCELLANEOUS) Here's a very minor fix for the title and the absence of tick marks on the right side:

    # Fix for: title + no tick marks on the right side of the plot
    ax2 = axLin.twinx()
    ax2.spines['left'].set_visible(False)
    ax2.tick_params(axis='y',which='both',labelright='off')
    

    Adding these lines will give you this: Answer2

    pythonmatplotlib

    0 讨论(0)
  • 2020-12-05 21:41

    I assume you want linear near the origin, log farther -- since `symlog' does it the other way around -- I couldn't come up with data that looked good like this, but you can put it together with the axes_grid:

    # linear and log axes for the same plot?
    # starting with the histogram example from 
    # http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html
    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    import numpy as np
    
    # Numbers from -50 to 50, with 0.1 as step
    xdomain = np.arange(-50,50, 0.1)
    
    axMain = plt.subplot(111)
    axMain.plot(xdomain, np.sin(xdomain))
    axMain.set_yscale('log')
    axMain.set_ylim((0.01, 0.5))
    divider = make_axes_locatable(axMain)
    axLin = divider.append_axes("top", size=2.0, pad=0.02, sharex=axMain)
    axLin.plot(xdomain, np.sin(xdomain))
    
    axLin.set_xscale('linear')
    axLin.set_ylim((0.5, 1.5))
    plt.title('Linear above, log below')
    
    plt.show()
    

    enter image description here

    0 讨论(0)
提交回复
热议问题