2012-05-16 24 views
18

Tôi đang cố gắng tạo ra một biểu đồ và tôi đang gặp một số vấn đề khi chú thích nó.Matplotlib: Thêm chuỗi như x-ve tùy chỉnh mà còn giữ nhãn đánh dấu (số) hiện có? Thay thế cho matplotlib.pyplot.annotate?

Biểu đồ của tôi có thang tỷ lệ log trên trục x, hiển thị thời gian. Những gì tôi muốn có thể làm là giữ các nhãn đánh dấu số hiện tại (nhưng không thể đoán trước) ở 100 đơn vị, 1000 đơn vị, 10000 đơn vị, vv nhưng cũng thêm nhãn đánh dấu tùy chỉnh vào trục x làm rõ hơn "con người "khoảng thời gian" có thể đọc được --- ví dụ: tôi muốn có thể gắn nhãn 'một tuần', 'một tháng', '6 tháng', v.v.

Tôi có thể sử dụng matplotlib.pyplot.annotate() để đánh dấu các điểm nhưng nó không thực sự làm những gì tôi muốn. Tôi không thực sự muốn văn bản và mũi tên trên đầu trang của đồ thị của tôi, tôi chỉ muốn thêm một vài dấu tick tùy chỉnh thêm. Bất kỳ ý tưởng?

Trả lời

16

Nếu bạn thực sự muốn thêm thêm bọ ve, bạn có thể lấy những cái hiện có bằng cách sử dụng axis.xaxis.get_majorticklocs(), thêm bất cứ điều gì bạn muốn thêm, và sau đó đặt ve bằng cách sử dụng axis.xaxis.set_ticks(<your updated array>).

Cách khác là thêm đường thẳng đứng using axvline. Ưu điểm là bạn không phải lo lắng về việc chèn dấu tùy chỉnh của bạn vào mảng hiện có, nhưng bạn sẽ phải chú thích các dòng theo cách thủ công.

Một giải pháp thay thế khác là thêm trục được liên kết với các dấu tùy chỉnh của bạn.

+1

Cảm ơn. Tôi nghĩ nó có ý nghĩa hơn khi thêm trục x thứ cấp. Việc trộn các nhãn số và chuỗi trục dẫn đến sự chồng chéo gây phiền toái và các vấn đề về định dạng vì vậy tôi sẽ chỉ đi với twiny(). :-) – FakeDIY

+1

so với câu hỏi này có thể được sử dụng cho bạn: http://stackoverflow.com/questions/10514315/how-to-add-a-second-x-axis-in-matplotlib –

12

Từ http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.xticks:

# return locs, labels where locs is an array of tick locations and 
# labels is an array of tick labels. 
locs, labels = xticks() 

Vì vậy, tất cả các bạn nên cần phải làm là có được locslabels và sau đó sửa đổi labels theo ý thích của bạn (dummy ví dụ):

labels = ['{0} (1 day)','{0} (1 weak)', '{0} (1 year)'] 
new_labels = [x.format(locs[i]) for i,x in enumerate(labels)] 

và sau đó chạy:

xticks(locs, new_labels) 
+0

Tác phẩm này, nhưng không hoàn toàn là những gì tôi muốn làm. Tôi có thể thấy rằng tôi có thể sử dụng xticks() để có được kết quả mong muốn cuối cùng nhưng tôi thực sự nghĩ rằng nó sẽ được neater và dễ dàng hơn để chỉ vẽ một trục x thứ hai như đề xuất dưới đây. Cảm ơn. – FakeDIY

+0

OK, bạn nên chấp nhận câu trả lời đó. Tôi đồng ý rằng đây là một hack (nhưng hoạt động để sử dụng trong nhà/sửa lỗi nhanh). – deinonychusaur

5

Đây là giải pháp của tôi. Các ưu điểm chính là:

  • Bạn có thể chỉ định các trục (hữu dụng cho các trục đôi hoặc nếu làm việc với nhiều trục đồng thời)
  • Bạn có thể chỉ định các trục (đặt bọ ve trên trục x hoặc y-axis)
  • Bạn có thể dễ dàng thêm các dấu tick mới trong khi vẫn giữ các dấu tự động mới
  • Nó tự động thay thế nếu bạn thêm dấu tích đã tồn tại.

Code:

#!/usr/bin/python 
from __future__ import division 
import matplotlib.pyplot as plt 
import numpy as np 

#Function to add ticks 
def addticks(ax,newLocs,newLabels,pos='x'): 
    # Draw to get ticks 
    plt.draw() 

    # Get existing ticks 
    if pos=='x': 
     locs = ax.get_xticks().tolist() 
     labels=[x.get_text() for x in ax.get_xticklabels()] 
    elif pos =='y': 
     locs = ax.get_yticks().tolist() 
     labels=[x.get_text() for x in ax.get_yticklabels()] 
    else: 
     print("WRONG pos. Use 'x' or 'y'") 
     return 

    # Build dictionary of ticks 
    Dticks=dict(zip(locs,labels)) 

    # Add/Replace new ticks 
    for Loc,Lab in zip(newLocs,newLabels): 
     Dticks[Loc]=Lab 

    # Get back tick lists 
    locs=list(Dticks.keys()) 
    labels=list(Dticks.values()) 

    # Generate new ticks 
    if pos=='x': 
     ax.set_xticks(locs) 
     ax.set_xticklabels(labels) 
    elif pos =='y': 
     ax.set_yticks(locs) 
     ax.set_yticklabels(labels) 


#Get numpy arrays 
x=np.linspace(0,2) 
y=np.sin(4*x) 

#Start figure 
fig = plt.figure() 
ax=fig.add_subplot(111) 

#Plot Arrays 
ax.plot(x,y) 
#Add a twin axes 
axr=ax.twinx() 

#Add more ticks 
addticks(ax,[1/3,0.75,1.0],['1/3','3/4','Replaced']) 
addticks(axr,[0.5],['Miguel'],'y') 

#Save figure 
plt.savefig('MWE.pdf') 
1

Tôi thích câu trả lời của Miguel trên. Làm việc khá tốt. Tuy nhiên, một điều chỉnh nhỏ đã được thực hiện. Sau đây:

# Get back tick lists 
locs=Dticks.keys() 
labels=Dticks.values() 

phải được thay đổi để

# Get back tick lists 
locs=list(Dticks.keys()) 
labels=list(Dticks.values()) 

từ đó, bằng Python 2.7 +/3, Dict.keys() và Dict.values ​​() dict_keys trở lại và dict_values ​​đối tượng, mà không matplotlib không giống như (rõ ràng). Thông tin thêm về hai đối tượng đó trong PEP 3106.

+0

Cảm ơn, tôi đã thêm đề xuất của bạn với câu trả lời của tôi. – Miguel