pythonmatplotlibrectangles

matplotlib.patches.Rectangle produces rectangles with unequal size of linewidth


I am using matplotlib to plot the columns of a matrix as separate rectangles using matplotlib.patches.Rectangle. Somehow, all the "inner" lines are wider than the "outer" lines? Does somebody know what's going on here? Is this related to this Github issue?

Here's an MRE:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.patches as patches

# set seed
np.random.seed(42)

# define number of cols and rows
num_rows = 5
num_cols = 5

# define gap size between matrix columns
column_gap = 0.3

# define linewidth
linewidth = 5

# Determine the width and height of each square cell
cell_size = 1  # Set the side length for each square cell

# Initialize the matrix
matrix = np.random.rand(num_rows, num_cols)

# Create the plot
fig, ax = plt.subplots(figsize=(8,6))

# Create a seaborn color palette (RdYlBu) and reverse it
palette = sns.color_palette("RdYlBu", as_cmap=True).reversed()

# Plot each cell individually with column gaps
for i in range(num_rows):
    for j in range(num_cols):
        
        # Compute the color for the cell
        color = palette(matrix[i, j])
        
        if column_gap > 0:
            edgecolor = 'black'
        else:
            edgecolor = None
        
        # Add a rectangle patch with gaps only in the x-direction
        rect = patches.Rectangle(
            (j * (cell_size + column_gap), i * cell_size),  # x position with gap applied to columns only
            cell_size,                                      # width of each cell
            cell_size,                                      # height of each cell
            facecolor=color,
            edgecolor=edgecolor,
            linewidth=linewidth
        )
        
        ax.add_patch(rect)

if column_gap > 0:
    
    # Remove the default grid lines and ticks
    ax.spines[:].set_visible(False)

# Set axis limits to fit all cells
ax.set_xlim(0, num_cols * (cell_size + column_gap) - column_gap)
ax.set_ylim(0, num_rows * cell_size)

# Disable x and y ticks
ax.set_xticks([])
ax.set_yticks([])

fig.show()

which produces:

rectangles with unequal linewidths


Solution

  • Your rectangles' edges are getting clipped by the axis boundaries.

    Add clip_on=False to Rectangle:

            rect = patches.Rectangle(
                (j * (cell_size + column_gap), i * cell_size),  # x position with gap applied to columns only
                cell_size,                                      # width of each cell
                cell_size,                                      # height of each cell
                facecolor=color,
                edgecolor=edgecolor,
                linewidth=linewidth,
                clip_on=False,
            )
    

    Output (small size for the demo):

    enter image description here

    To better see what's going on, let's add some transparency to your rectangles and change the axis background color:

    ax.patch.set_facecolor('red')
    

    enter image description here