2013-08-22 40 views
5

Tôi làm cách nào để chú thích phạm vi dữ liệu của mình? Ví dụ: giả sử dữ liệu từ x = 5 đến x = 10 lớn hơn một số lần cắt, làm cách nào tôi có thể chỉ ra rằng trên biểu đồ. Nếu tôi đã chú thích bằng tay, tôi sẽ chỉ vẽ một khung lớn phía trên phạm vi và viết chú thích của tôi lên trên khung.Phạm vi chú thích dữ liệu trong matplotlib

Gần nhất tôi thấy là sử dụng arrowstyle='<->'connectionstyle='bar', để làm cho hai mũi tên trỏ đến các cạnh của dữ liệu của bạn với một đường nối đuôi của chúng. Nhưng điều đó không hoàn toàn làm điều đúng; văn bản bạn nhập cho chú thích sẽ kết thúc dưới một trong các mũi tên, chứ không phải phía trên thanh.

Đây là nỗ lực của tôi, cùng với kết quả của nó:

annotate(' ', xy=(1,.5), xycoords='data', 
      xytext=(190, .5), textcoords='data', 
      arrowprops=dict(arrowstyle="<->", 
          connectionstyle="bar", 
          ec="k", 
          shrinkA=5, shrinkB=5, 
          ) 
      ) 

Annotation attempt

Một vấn đề khác với giải pháp đã cố gắng của tôi là hình dạng bình phương của khung chú thích không thực sự làm cho nó rõ ràng rằng tôi làm nổi bật một phạm vi (không giống như, ví dụ, một dấu ngoặc nhọn). Nhưng tôi cho rằng điều đó thật là khó tính vào thời điểm này.

+0

sử dụng hai chú thích, một với văn bản, nhưng không có mũi tên, và một với mũi tên, nhưng không có bản văn. Ngoài ra, hãy xem 'axvspan' http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.axvspan – tacaswell

+0

Nó cũng là cách tốt nhất để hiển thị những gì bạn đã thử (với một đoạn mã). – tacaswell

+0

@tcaswell Tôi đã nghĩ đến việc sử dụng hai chú thích, nhưng điều đó sẽ liên quan đến việc định vị văn bản theo cách thủ công và phải cập nhật thủ công cả hai cách, nếu, phạm vi di chuyển. Dường như nó sẽ là một vấn đề đủ phổ biến mà một giải pháp tối ưu hơn sẽ tồn tại. – ari

Trả lời

4

Bạn chỉ có thể quấn nó tất cả trong một hàm:

def add_range_annotation(ax, start, end, txt_str, y_height=.5, txt_kwargs=None, arrow_kwargs=None): 
    """ 
    Adds horizontal arrow annotation with text in the middle 

    Parameters 
    ---------- 
    ax : matplotlib.Axes 
     The axes to draw to 

    start : float 
     start of line 

    end : float 
     end of line 

    txt_str : string 
     The text to add 

    y_height : float 
     The height of the line 

    txt_kwargs : dict or None 
     Extra kwargs to pass to the text 

    arrow_kwargs : dict or None 
     Extra kwargs to pass to the annotate 

    Returns 
    ------- 
    tuple 
     (annotation, text) 
    """ 

    if txt_kwargs is None: 
     txt_kwargs = {} 
    if arrow_kwargs is None: 
     # default to your arrowprops 
     arrow_kwargs = {'arrowprops':dict(arrowstyle="<->", 
          connectionstyle="bar", 
          ec="k", 
          shrinkA=5, shrinkB=5, 
          )} 

    trans = ax.get_xaxis_transform() 

    ann = ax.annotate('', xy=(start, y_height), 
         xytext=(end, y_height), 
         transform=trans, 
         **arrow_kwargs) 
    txt = ax.text((start + end)/2, 
        y_height + .05, 
        txt_str, 
        **txt_kwargs) 


    if plt.isinteractive(): 
     plt.draw() 
    return ann, txt 

Cách khác,

start, end = .6, .8 
ax.axvspan(start, end, alpha=.2, color='r') 
trans = ax.get_xaxis_transform() 
ax.text((start + end)/2, .5, 'test', transform=trans) 
+0

Nó không phải là một hoạt động đủ phổ biến để có được phương pháp riêng của mình? – ari

+0

Tôi không biết một cái hiện có, nhưng tôi chỉ viết một cái;) Nếu bạn có thể cung cấp một số nguồn cấp dữ liệu trở lại bằng cách sử dụng điều, tôi sẽ đề nghị thêm vào thư viện này như là một built in – tacaswell

+0

Cả hai đều là lựa chọn tốt, cảm ơn vì đã chia sẻ chúng. Chức năng bạn cung cấp đã đủ cho hầu hết các trường hợp, nhưng nếu bạn đang tìm cách để cải thiện nó, tôi có thể nghĩ ra một số gợi ý. – ari

Các vấn đề liên quan