Нарисуйте ширину линии внутри прямоугольника Matplotlib - PullRequest
0 голосов
/ 07 марта 2020

У меня проблемы с рисованием прямоугольников в matplotlib с использованием патчей. Когда linewidth предоставляется для патчей. Прямоугольник, граница рисуется снаружи прямоугольника. Вот пример:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig, ax = plt.subplots(1)
rect = patches.Rectangle((1, 1), 1, 1, facecolor = 'blue')
rect2 = patches.Rectangle((1, 2.1), 1, 1, facecolor = 'none', edgecolor = 'black', linewidth = 6)
ax.add_patch(rect)
ax.add_patch(rect2)

ax.set_xlim([0, 3.5])
ax.set_ylim([0, 3.5])

вот результат:

Matplotlib rectangles

Обратите внимание, что граница нарисована снаружи поля так, что рамка + граница теперь превышает размер синей коробки. Мне бы хотелось, чтобы граница рисовалась внутри рамки, чтобы она всегда была такого же размера, что и синяя рамка, независимо от ширины линии.

Desired result

Я пробовал это в двух другими способами, и ни один из них не удовлетворял:

  1. Преобразование ширины линии из абсолютных единиц в единицы данных, а затем вычисление меньшего прямоугольника, который можно нарисовать с нормальной границей, совпадающей с другим прямоугольником.
  2. Изучите некоторые функции offsetbox, как в этого поста , хотя я не продвинулся слишком далеко, так как не мог понять, как правильно указать pad.

Буду признателен за любую помощь!

1 Ответ

0 голосов
/ 07 марта 2020

Самый простой подход - установить прямоугольник клипа, который скрывает все, что находится за пределами прямоугольника. Поскольку у вас уже есть прямоугольник, его можно использовать для обрезания.

Поскольку граница рисуется по центру линии границы, половина ее будет обрезана. Это можно решить, установив ширину, чтобы удвоить желаемую ширину.

Обратите внимание, что для того, чтобы усечение работало должным образом, прямоугольник уже необходимо преобразовать в координаты осей. Итак, сначала добавьте прямоугольный патч к топору, и только затем используйте is, чтобы установить отсечение.

Также обратите внимание, что с параметрами по умолчанию прямоугольник использует один и тот же цвет для внутренней и тонкой границ. Установка нулевой ширины линии гарантирует, что она не будет рисоваться за пределами прямоугольника.

Аналогично, эллипсы могут быть нарисованы с линией только внутри.

В приведенном ниже коде используется толщина 10 и некоторые дополнительные пунктирные красные линии, чтобы проиллюстрировать происходящее.

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig, ax = plt.subplots()

pad = 0.1 # distance between the rectangles
for i in range(3):
    for j in range(2):
        x = .5 + i * (1 + pad)
        y =  .5 + j * (1 + pad)
        if i == j:
            patch = patches.Rectangle((x, y), 1, 1, facecolor='blue', linewidth=0)
        elif i < 2:
            patch = patches.Rectangle((x, y), 1, 1, facecolor='none', edgecolor='black',
                                     linewidth=10*2 if j == 0 else 10)
        else:
            patch = patches.Ellipse((x+0.5, y+0.5), 1, 1, facecolor='none', edgecolor='black',
                                     linewidth=10*2 if j == 0 else 10)
        ax.add_patch(patch)
        if j == 0:
            patch.set_clip_path(patch)

for i in range(3):
    x = .5 + i * (1 + pad)
    for s in 0,1:
        ax.axvline (x+s, color='crimson', ls=':', lw=1)
for j in range(2):
    y =  .5 + j * (1 + pad)
    for s in 0,1:
        ax.axhline (y+s, color='crimson', ls=':', lw=1)

ax.set_xlim([0, 4.0])
ax.set_ylim([0, 3.0])
ax.set_aspect('equal')
plt.show()

На рисунке ниже показан стандартный способ рисования вверху и обрезка с двойной шириной линии внизу.

resulting plot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...