Подтвердить что ты не робот

Коробка вокруг текста в matplotlib

Как можно сделать прямоугольник вокруг текста в matplotlib? У меня есть текст на трех разных строках и в трех разных цветах:

 ax.text(2,1, 'alpha', color='red')
 ax.text(2,2, 'beta', color='cyan')
 ax.text(2,3, 'epsilon', color='black')

Я видел учебник http://matplotlib.org/users/recipes.html (последний пример), но я не могу решить проблему. Спасибо заранее.

4b9b3361

Ответ 1

В качестве примера, связанного с упоминаниями, вы можете использовать bbox kwarg для добавления поля.

Я предполагаю, что вы смущены тем, как установить цвет и т.д. в поле? В качестве краткого примера:

import matplotlib.pyplot as plt
fig, ax = plt.subplots()

ax.text(0.5, 0.8, 'Test', color='red', 
        bbox=dict(facecolor='none', edgecolor='red'))

ax.text(0.5, 0.6, 'Test', color='blue', 
        bbox=dict(facecolor='none', edgecolor='blue', pad=10.0))

ax.text(0.5, 0.4, 'Test', color='green', 
        bbox=dict(facecolor='none', edgecolor='green', boxstyle='round'))

ax.text(0.5, 0.2, 'Test', color='black', 
        bbox=dict(facecolor='none', edgecolor='black', boxstyle='round,pad=1'))

plt.show()

enter image description here

Последние два являются "Fancy" bbox-патчами, поэтому отступы и т.д. задаются другим способом. (Что довольно неприятно для простых вещей, таких как заполнение, хотя это делает реализацию проще за кадром.)

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

Ответ 2

enter image description here Есть некоторая документация в Интернете где-то (лучшее, что я могу найти быстро, http://matplotlib.org/users/annotations_guide.html) для использования VPacker и AnnotationBbox для объединения несколько текстов с различными свойствами шрифта.

from matplotlib.offsetbox import TextArea, VPacker, AnnotationBbox
from pylab import *
fig = figure(1)
ax = gca()
texts = ['alpha','beta','epsilon']
colors = ['red','cyan','black']
Texts = []
for t,c in zip(texts,colors):
    Texts.append(TextArea(t,textprops=dict(color=c)))
texts_vbox = VPacker(children=Texts,pad=0,sep=0)
ann = AnnotationBbox(texts_vbox,(.02,.5),xycoords=ax.transAxes,
                            box_alignment=(0,.5),bboxprops = 
                            dict(facecolor='wheat',boxstyle='round',color='black'))
ann.set_figure(fig)
fig.artists.append(ann)

Я не уверен, почему нужны две последние две строки. Я бы подумал, что для второго хватит.

Ответ 3

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

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

fig, axs = plt.subplots(1,1)

t1 = axs.text(0.4,0.6, 'Hello world line 1', ha='center', color='red', weight='bold', transform=axs.transAxes)
t2 = axs.text(0.5,0.5, 'Hello world line 2', ha='center', color='green', weight='bold', transform=axs.transAxes)
t3 = axs.text(0.6,0.4, 'Hello world line 3', ha='center', color='blue', weight='bold', transform=axs.transAxes)

fig.canvas.draw()

textobjs = [t1,t2,t3]

xmin = min([t.get_window_extent().xmin for t in textobjs])
xmax = max([t.get_window_extent().xmax for t in textobjs])
ymin = min([t.get_window_extent().ymin for t in textobjs])
ymax = max([t.get_window_extent().ymax for t in textobjs])

xmin, ymin = fig.transFigure.inverted().transform((xmin, ymin))
xmax, ymax = fig.transFigure.inverted().transform((xmax, ymax))

rect = patches.Rectangle((xmin,ymin),xmax-xmin,ymax-ymin, facecolor='grey', alpha=0.2, transform=fig.transFigure)

axs.add_patch(rect)

Возможно, вы захотите добавить небольшой буфер и т.д., но идея останется прежней.

enter image description here