Search code examples
matplotlibdrawing

How to keep matplotlib grid constrained while drawing outside of the grid?


I'm trying to draw the following image in matplotlib:

Surface code

I don't care about the red dot or yellow circle for now. All I'm trying to do is get the grid drawn with the semicircles. A key point is that I want the outlines to show like in the picture. At the moment, the code I have is this:

import matplotlib.pyplot as plt
    
N = 5
colors = [(111,187,255),(185,239,133)] # Blue and green
plaquettecolors = ["#b9ef85ff", "#6fbbffe5"] # Green and blue
rowcolor = colors*((N-1)//2)
fig, ax = plt.subplots()


# Build the matrix for the colours
bulkcolors = []
for y in range(N-1):
    bulkcolors.extend(rowcolor[::(-1)**y])
    greenCircle = plt.Circle(
        (y,-0.5 + (1+(-1)**(y+1))*(N-1)/2),
        0.5,
        color=plaquettecolors[0],
        fill=True,
        ec="black",
        lw = 2,
        zorder=0
        )
    blueCircle = plt.Circle(
        (-0.5 + (1+(-1)**y)*(N-1)/2,y),
        0.5,
        color=plaquettecolors[1],
        fill=True,
        ec = "black",
        lw = 2,
        zorder=0)
    ax.add_patch(greenCircle)
    ax.add_patch(blueCircle)

# Reshape things.
bulkcolors = np.array(bulkcolors)
bulkcolors = bulkcolors.reshape((N-1, N-1,-1))

#ax.axis("off")
ax.matshow(bulkcolors)
plt.xticks(range(-1,N))
plt.yticks(range(-1,N))
ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2)
ax.set_xticks(np.arange(-0.5, N-1, 1))
ax.set_yticks(np.arange(-0.5, N-1, 1))
ax.tick_params(which="major", bottom=False, left=False)
plt.show()

The issue is that I get the following: With matplotlib

What I'm hoping for is a way to remove the grid lines outside of the checkerboard pattern, as well as the numbers. Any tips to get this working would be appreciated!


Solution

  • Hide the gridlines and draw horizontal and vertical lines instead:

    ax.axis("off")
    ax.matshow(bulkcolors)
    plt.xlim(-1.1, N-.9)
    plt.ylim(-1.1, N-.9)
    for i in np.arange(-.5, N-1, 1):
        plt.hlines(i, -.5, N-1.5, lw=2, color='k')
        plt.vlines(i, -.5, N-1.5, lw=2, color='k')
    

    enter image description here