2015-05-18 11 views
7

mam działkę, gdzie chciałbym opisywanie określonym miejscu na osi x ze strzałką i etykietą:Czy możliwe jest zakotwiczenie adnotacji matplotlib do współrzędnych danych na osi X, ale do względnej lokalizacji na osi Y?

  • Położenie końcówki strzałki musi być dokładnie określony we współrzędnych danych .
  • Strzałka powinna być pionowa, dlatego współrzędne X tępego końca strzałki (i etykiety tekstowej) powinny być również określone dokładnie we współrzędnych danych.
  • Jednak najlepiej byłoby móc określić położenie y tępego końca strzałki względem ramki ograniczającej oś, a nie dane.

Mój obecny roztwór roboczy polega na określeniu położenia zarówno końcówki strzałki i etykiety w danych współrzędnych:

import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib.transforms import blended_transform_factory 


x = np.random.randn(10000) 
r = 3 
label = 'foo' 
arrowprops = dict(fc='r', ec='k') 

def make_example_plot(): 
    fig, ax = plt.subplots(1, 1) 
    ax.hold(True) 
    counts, edges, patches = ax.hist(x) 
    return fig, ax 

fig, ax = make_example_plot() 
lo, hi = ax.get_ylim() 
ax.annotate(label, xy=(r, 0), xycoords='data', 
      xytext=(r, hi * 1.1), textcoords='data', fontsize='xx-large', 
      ha='center', va='center', color='r', arrowprops=arrowprops) 
ax.set_ylim(0, hi * 1.3) 

enter image description here

wolałbym mieć pobyt etykiet w stałej pozycji w y niezależnie od tego, w jaki sposób przeskalowuję lub przesuwanie osi y. Mogę osiągnąć pożądany efekt dla zwykłego etykiety tekstowej przekazując mieszane transformację XY ax.text:

fig, ax = make_example_plot() 
tform = blended_transform_factory(ax.transData, ax.transAxes) 
ax.text(r, 0.9, label, fontsize='xx-large', color='r', transform=tform) 

enter image description here

Jeśli rozmnażać ta następnie przesunąć lub przeskalować go, widać, że ruchy tekstowe w x względem ramki ograniczającej oś, ale pozostaje w ustalonej pozycji w y. Oczywiście to wciąż nie daje mi strzały. Miałem nadzieję, że mogę korzystać z tego samego podejścia z ax.annotate, ale to nie wydają się działać:

fig, ax = make_example_plot() 
tform = blended_transform_factory(ax.transData, ax.transAxes) 
ax.annotate(label, xy=(r, 0), xycoords='data', transform=tform, 
      xytext=(r, 0.9), textcoords='data', fontsize='xx-large', 
      ha='center', va='center', color='r', arrowprops=arrowprops) 

Etykieta i strzały są umieszczone na y = 0.9 we współrzędnych danych, a nie na poziomie 90% całkowitej wysokości oś Y:

enter image description here

Czy istnieje sposób, aby osobno określić ramy odniesienia dla xiy przekształceń stosowanych do matplotlib.text.Annotation?

Odpowiedz

7

Przekaż transformację do parametrów xycoords i textcoords zamiast do parametru transform. Podobnie jak:

fig, ax = make_example_plot() 
tform = blended_transform_factory(ax.transData, ax.transAxes) 
ax.annotate(label, xy=(r, 0), xycoords=tform, 
      xytext=(r, 0.9), textcoords=tform, fontsize='xx-large', 
      ha='center', va='center', color='r', arrowprops=arrowprops) 
+0

Bardzo ładne! Opcja bezpośredniego przekazywania transformacji dla argumentów 'xycoords =' i 'textcoords =' nie jest wymieniona w dokumentacji. –

+0

To naprawdę nie jest tak oczywiste. W [paplot.annotation] (http://matplotlib.org/1.4.0/api/pyplot_api.html#matplotlib.pyplot.annotate) znajduje się następująca uwaga: _ "Możesz użyć instancji Transform lub Artist. Adnotowanie osi, aby uzyskać więcej szczegółów "_. Prowadzi to do [Używanie złożonych współrzędnych z adnotacjami] (http://matplotlib.org/1.4.0/users/annotations_guide.html#using-complex-coordinate-withannotation), co daje kilka dobrych przykładów. – titusjan

+1

Wow, dokumentacja może naprawdę zrobić z pewnym wyjaśnieniem ... –

Powiązane problemy