¿Establecer el borde del rectángulo de matplotlib fuera del ancho especificado?

¿Hay una manera de especificar el borde para el parche Rectangle de matplotlib para que el borde esté fuera del dominio especificado? En photoshop, esto se llamaría “posición de trazo”, por ejemplo. Permítame ilustrar con un ejemplo:

import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Rectangle # Here's my "image" X = np.arange(16).reshape(4,4) # Suppose I want to highlight some feature in the middle boxes. fig = plt.figure() ax = fig.add_subplot(111) ax.imshow(X, cmap=plt.cm.gray, interpolation='nearest') ax.add_patch( Rectangle((0.5, 0.5), 2, 2, fc='none', ec='r') ) plt.show() 

Esto produce lo siguiente:

introduzca la descripción de la imagen aquí

Sin embargo, si se modifica lo anterior como sigue

 ax.add_patch( Rectangle((0.5, 0.5), 2, 2, fc='none', ec='r', lw=10) ) 

Obtengo la figura:

introduzca la descripción de la imagen aquí

Como puede ver, el borde está posicionado en el centro a lo largo del borde del dominio del objeto Rectangle, por lo que sangra en este dominio. ¿Es posible forzar que el borde del borde esté estrictamente fuera del dominio del Rectángulo?

Puede usar un AnnotationBbox dentro del cual se coloca un AuxTransformBox . Este AuxTransformBox contendría un rectángulo proxy del tamaño deseado. Esto puede hacerse invisible (por ejemplo, fc='none', ec='none' ). Su única función es escalar el AuxTransformBox al tamaño correcto. Ahora se puede dar a AnnotationBbox un borde de un ancho de línea grande. Si está apretado contra el AuxTransformBox el borde solo comenzará donde termina el AuxTransformBox . Para permitir que el borde se ajuste firmemente, se puede ajustar la almohadilla de pad a la mitad del ancho de línea del borde. Dado que el relleno se da en unidades de tamaño de fuente, es el tamaño de fuente el que debe establecerse en el ancho de línea y el relleno en 0.5, pad=0.5,fontsize=linewidth . Tenga en cuenta que parece que un relleno ligeramente más grande de 0.52 se ve mejor en la ttwig; En cualquier caso, esto se puede ajustar a gusto.

Suena complicado, pero el código se puede copiar y pegar para usar en cualquier lugar donde normalmente se use un rectángulo.

 import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from matplotlib.offsetbox import AnnotationBbox, AuxTransformBox # Here's my "image" X = np.arange(16).reshape(4,4) # Suppose I want to highlight some feature in the middle boxes. fig = plt.figure() ax = fig.add_subplot(111) ax.imshow(X, cmap=plt.cm.gray, interpolation='nearest', aspect="auto") linewidth=14 xy, w, h = (0.5, 0.5), 2, 2 r = Rectangle(xy, w, h, fc='none', ec='gold', lw=1) offsetbox = AuxTransformBox(ax.transData) offsetbox.add_artist(r) ab = AnnotationBbox(offsetbox, (xy[0]+w/2.,xy[1]+w/2.), boxcoords="data", pad=0.52,fontsize=linewidth, bboxprops=dict(facecolor = "none", edgecolor='r', lw = linewidth)) ax.add_artist(ab) plt.show() 

introduzca la descripción de la imagen aquí