Search code examples
pythonmatplotlibxticksgridlines

How to do xticklabel with different major grid spacing


How to plot a chart with minor grid of 1, major grid of 10, and with xticklabels increment 20 units?

Here is my sample code and output with xticklabels increment every 10 units:

plt.figure(figsize=(10, 10))
ax = plt.gca()
major_ticks = np.arange(0, 60, 10)    
minor_ticks = np.arange(0, 60, 1)
ax.set_xticks(major_ticks)
ax.set_xticks(minor_ticks, minor=True)
ax.set_yticks(major_ticks)
ax.set_yticks(minor_ticks, minor=True)
ax.grid(which='major')
ax.grid(which='minor', alpha=0.5)
ax.set_aspect('equal')

enter image description here

But then I wanted to display the xticklabels and yticklabels with the increment of 20 instead of 10, as shown here like this:

enter image description here

Any idea how to accomplish this? Thanks


Solution

  • Just add the following 4 lines to the end of your code: You just have to hide every second major tick label. That's pretty much it to get what you want. [1::2] indexing means start from the second index and take every second element from there. I have to start from the second index because the tick label at the first index is 0 which you do not want to remove.

    EDIT: IF you just want the major ticks at the locations where you have tick labels, you can do the following modifications (marked by an arrow <---). Yo might find the official docs helpful.

    Plot without the major ticks but with minor ticks

    # Hiding for x-axis
    for t in ax.xaxis.get_major_ticks()[1::2]:
        t.label.set_visible(False)
        t.tick1On = False # <----
    
    # Hiding for y-axis
    for t in ax.yaxis.get_major_ticks()[1::2]:
        t.label.set_visible(False)    
        t.tick1On = False # <----
    

    enter image description here

    Plot without the minor and major ticks

    If you also want to hide the minor ticks, you can do the following in addition to the above code

    for t in ax.xaxis.get_minor_ticks():
        t.tick1On = False
        # t._apply_params(width=0) # suggested by Jayjayyy
    
    for t in ax.yaxis.get_minor_ticks():
        t.tick1On = False     
        # t._apply_params(width=0) # suggested by Jayjayyy
    

    The direct way avoiding all for loops is as suggested by Jayjayyy

    ax.tick_params(axis='both', which='minor', width=0)   
    

    enter image description here