Search code examples
pythonmatplotlibxticksgridlinesyticks

Change grid interval and specify tick labels


I am trying to plot counts in gridded plots, but I haven't been able to figure out how to go about it.

I want:

  1. to have dotted grids at an interval of 5;

  2. to have major tick labels only every 20;

  3. for the ticks to be outside the plot; and

  4. to have "counts" inside those grids.

I have checked for potential duplicates, such as here and here, but have not been able to figure it out.

This is my code:

import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter

for x, y, count in data.values():

    fig = plt.figure()
    ax = fig.add_subplot(111)

    ax.annotate(count, xy = (x, y), size = 5)
    # overwrites and I only get the last data point

    plt.close()
    # Without this, I get a "fail to allocate bitmap" error.

plt.suptitle('Number of counts', fontsize = 12)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.axes().set_aspect('equal')

plt.axis([0, 1000, 0, 1000])
# This gives an interval of 200.

majorLocator   = MultipleLocator(20)
majorFormatter = FormatStrFormatter('%d')
minorLocator   = MultipleLocator(5)
# I want the minor grid to be 5 and the major grid to be 20.
plt.grid()

This is what I get.

This is what I get:


Solution

  • There are several problems in your code.

    First the big ones:

    1. You are creating a new figure and a new axes in every iteration of your loop → put fig = plt.figure and ax = fig.add_subplot(1,1,1) outside of the loop.

    2. Don't use the Locators. Call the functions ax.set_xticks() and ax.grid() with the correct keywords.

    3. With plt.axes() you are creating a new axes again. Use ax.set_aspect('equal').

    The minor things: You should not mix the MATLAB-like syntax like plt.axis() with the objective syntax. Use ax.set_xlim(a,b) and ax.set_ylim(a,b)

    This should be a working minimal example:

    import numpy as np
    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    
    # Major ticks every 20, minor ticks every 5
    major_ticks = np.arange(0, 101, 20)
    minor_ticks = np.arange(0, 101, 5)
    
    ax.set_xticks(major_ticks)
    ax.set_xticks(minor_ticks, minor=True)
    ax.set_yticks(major_ticks)
    ax.set_yticks(minor_ticks, minor=True)
    
    # And a corresponding grid
    ax.grid(which='both')
    
    # Or if you want different settings for the grids:
    ax.grid(which='minor', alpha=0.2)
    ax.grid(which='major', alpha=0.5)
    
    plt.show()
    

    Output is this:

    result