2013-06-13 13 views
20

jak można zrobić pudełko wokół tekstu w matplotlib? mam tekst na trzech różnych liniach oraz w trzech różnych kolorach:Pudełko dookoła tekstu w matplotlib

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

Widziałem tutorial http://matplotlib.org/users/recipes.html (ostatni przykład), ale nie mogę rozwiązać ten problem. Z góry dzięki.

+1

Jaki jest twój problem z ostatnim przykładem receptur? –

+0

@David W tym przykładzie jest tylko 1 wiersz tekstu. Poszukuję, jak to możliwe, że ma to samo pudełko wokół tekstu, który napisałem. Po przepisie mogę napisać tekst w jednym wierszu, jak w przykładzie (textstr = '$ \ mu =%. 2f $ \ n $ \ mathrm {median} =%. 2f $ \ n $ \ sigma =%. 2f $'), ale jak można zmienić kolor tekstu? –

Odpowiedz

46

Jako przykład, do którego link został dodany do wzmianek, można użyć pola the bbox kwarg, aby dodać pole.

Zakładam, że nie masz pojęcia, jak ustawić kolor, itp. Pudełka? Jako szybki przykład:

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

ostatnie dwa są „wyszukane” plastry bbox, więc wyściółka itp mieści się w inny sposób. (Co jest dość denerwujące dla prostych rzeczy, takich jak wypełnianie, ale sprawia, że ​​implementacja jest prostsza za kulisami.)

Ponadto, jeśli etykietujesz rzeczy w swojej fabule, prawdopodobnie okaże się, że annotate jest lepszym wybór. Między innymi umożliwia umieszczanie tekstu w pozycji w punktach z określonej pozycji danych.

+0

Dziękuję za odpowiedź, ale prawdopodobnie nie wyjaśniłem dobrze problemu, który mam. To, czego potrzebuję, to umieszczenie trzech linii tekstowych w jednym polu. –

+0

Ah! I zakładając różne kolory, zakładam? Jest to od dawna ograniczone matplotlib. (Dyskutowano o zmianach hurtowych w backendie renderowania tekstu, który by na to pozwolił.) Zasadniczo masz dwie opcje. 1) Użyj lateksu (będziesz potrzebował "pełnego" lateksu, a nie tylko matematycznego mate- mentu), lub 2) Wykreśl je osobno i narysuj ramkę wokół wyniku. Obie opcje są tutaj pokazane, nawiasem mówiąc: http://stackoverflow.com/questions/9169052/partial-coloring-of-text-in-matplotlib –

7

Rozwiązaniem może być poznanie obwiedni z obiektów tekstowych i samodzielne wygenerowanie ramki. To nie jest bardzo wygodne. Być może mój przykład może zostać poprawiony, transformacje zawsze trochę mnie dezorientują.

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) 

Możesz dodać mały bufor itp., Ale pomysł pozostanie taki sam.

enter image description here

10

enter image description here Istnieją pewne dokumentacji elektronicznej gdzieś (najlepiej mogę znaleźć szybko to http://matplotlib.org/users/annotations_guide.html) za korzystanie VPacker oraz AnnotationBbox ułożyła kilka tekstów o różnej właściwości czcionki.

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) 

Nie jestem pewien, dlaczego potrzebne są dwie ostatnie linie. Sądzę, że wystarczą sekundy do końca.

Powiązane problemy