Sửa đổi văn bản nhãn tick


215

Tôi muốn thực hiện một số sửa đổi cho một vài nhãn đánh dấu được chọn trong một âm mưu.

Ví dụ: nếu tôi làm:

label = axes.yaxis.get_major_ticks()[2].label
label.set_fontsize(size)
label.set_rotation('vertical')

kích thước phông chữ và hướng của nhãn tick được thay đổi.

Tuy nhiên, nếu thử:

label.set_text('Foo')

nhãn tick không được sửa đổi. Ngoài ra nếu tôi làm:

print label.get_text()

không có gì được in

Đây là một số lạ hơn. Khi tôi thử điều này:

 from pylab import *
 axes = figure().add_subplot(111)
 t = arange(0.0, 2.0, 0.01)
 s = sin(2*pi*t)
 axes.plot(t, s)
 for ticklabel in axes.get_xticklabels():
     print ticklabel.get_text()

Chỉ các chuỗi trống được in, nhưng cốt truyện chứa các dấu tick được dán nhãn là '0,0', '0,5', '1.0', '1.5' và '2.0'.


Bạn có thể cung cấp lô mà bạn đã sử dụng để lấy nhãn từ?
Claudio

Bạn đang nhận được nhãn trống vì bạn chưa vẽ khung vẽ. Nếu bạn gọi draw()trước khi thử in nhãn, bạn sẽ nhận được những gì bạn mong đợi. Rất tiếc, việc đặt các nhãn đánh dấu riêng lẻ là một điều khó khăn hơn (điều xảy ra là công cụ định vị và định dạng đánh dấu đã không được đặt lại và nó sẽ ghi đè lên mọi thứ khi bạn set_text). Tôi sẽ thêm một ví dụ sau, nếu ai đó không đánh bại tôi. Tôi phải bắt xe buýt, vào lúc này, mặc dù.
Joe Kington

@JoeKington: Tuyệt vời! Nhìn về phía trước để xem sửa chữa của bạn.
repoman

@repoman - Chà, có vẻ như tôi đã nói một cú chạm quá sớm. Những gì tôi có trong tâm trí làm việc cho các phiên bản cũ hơn của matplotlib, nhưng không phải là phiên bản mới nhất. Tôi cần phải đào thêm một chút. Điều đó đã được nói, điều này không nên phức tạp như nó ...
Joe Kington

Câu trả lời:


298

Hãy cẩn thận: Trừ khi ticklabels đã được đặt thành một chuỗi (như thường thấy trong ví dụ như boxplot), điều này sẽ không hoạt động với bất kỳ phiên bản nào của matplotlib mới hơn 1.1.0. Nếu bạn đang làm việc từ chủ github hiện tại, điều này sẽ không hoạt động. Tôi không chắc vấn đề là gì ... Đây có thể là một thay đổi ngoài ý muốn hoặc có thể không ...

Thông thường, bạn sẽ làm một cái gì đó dọc theo những dòng này:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# We need to draw the canvas, otherwise the labels won't be positioned and 
# won't have values yet.
fig.canvas.draw()

labels = [item.get_text() for item in ax.get_xticklabels()]
labels[1] = 'Testing'

ax.set_xticklabels(labels)

plt.show()

nhập mô tả hình ảnh ở đây

Để hiểu lý do tại sao bạn cần phải nhảy qua rất nhiều vòng, bạn cần hiểu thêm một chút về cách cấu trúc matplotlib.

Matplotlib cố tình tránh thực hiện định vị "tĩnh" của bọ ve, v.v., trừ khi nó được thông báo rõ ràng. Giả định là bạn sẽ muốn tương tác với cốt truyện, và do đó, giới hạn của cốt truyện, tiếng tích tắc, tiếng tích tắc, v.v. sẽ thay đổi linh hoạt.

Do đó, bạn không thể chỉ đặt văn bản của nhãn đánh dấu đã cho. Theo mặc định, nó được đặt lại bởi Trình định vị và Định dạng của trục mỗi khi vẽ sơ đồ.

Tuy nhiên, nếu Bộ định vị và Trình định dạng được đặt thành tĩnh ( FixedLocatorFixedFormatter, tương ứng), thì nhãn đánh dấu vẫn giữ nguyên.

Đây là những gì set_*ticklabelshoặc ax.*axis.set_ticklabelslàm.

Hy vọng rằng điều đó làm cho nó rõ ràng hơn một chút về lý do tại sao việc thay đổi một nhãn tick riêng lẻ lại hơi phức tạp.

Thông thường, những gì bạn thực sự muốn làm chỉ là chú thích một vị trí nhất định. Trong trường hợp đó, nhìn vào annotate, thay vào đó.


10
điều này dường như không hoạt động với phiên bản hiện tại (1.20)!
Andrew Jaffe

1
Nếu ticklabels đã được đặt thành một chuỗi như trong ví dụ như boxplot, thì nó vẫn hoạt động. Điều này có thể rõ ràng, nhưng vì dòng đầu tiên của câu trả lời là nó không hoạt động trên các phiên bản matplotlib mới hơn, người dùng có thể bỏ qua hoàn toàn (tôi đã làm ban đầu). Có thể đề cập ngắn gọn này.
joelostblom

2
tôi nghĩ bạn có thể ngưng tụ nó xuống plt.gca (). set_xticklabels (nhãn)
alexey

Điều gì sẽ xảy ra nếu tôi muốn phông chữ của "thử nghiệm" boldtrong khi những người khác sử dụng phông chữ của "ánh sáng". Có cách nào để làm điều đó?
steven

1
đối với những người sử dụng điều này trong một máy tính xách tay jupyter có thể được hưởng lợi từ việc lưu ý đó fig.canvas.draw()là rất quan trọng
wander95

95

Người ta cũng có thể làm điều này với pylabxticks

import matplotlib
import matplotlib.pyplot as plt
x = [0,1,2]
y = [90,40,65]
labels = ['high', 'low', 37337]
plt.plot(x,y, 'r')
plt.xticks(x, labels, rotation='vertical')
plt.show()

http://matplotlib.org/examples/ticks_and_spines/ticklabels_demo_rotation.html


Đây là một giải pháp đơn giản và hoạt động với pyplot 1.5.1. Điều này nên được nâng cao.
Wordsmith

Mặc dù câu hỏi không yêu cầu điều này, tôi đánh giá cao rằng ví dụ này cho phép bạn đặt vị trí của bọ ve cùng lúc với sửa đổi nhãn của chúng.
nhật thực

Từ các tài liệu matplotlib hiện đại : "pylab không được dùng nữa và việc sử dụng nó bị ngăn cản mạnh mẽ vì ô nhiễm không gian tên. Thay vào đó, hãy sử dụng pyplot."
Nathaniel Jones

93

Trong các phiên bản mới hơn matplotlib, nếu bạn không đặt nhãn tick với một loạt các strgiá trị, chúng ''theo mặc định (và khi cốt truyện được vẽ, các nhãn chỉ đơn giản là các giá trị tick). Biết rằng, để có được đầu ra mong muốn của bạn sẽ cần một cái gì đó như thế này:

>>> from pylab import *
>>> axes = figure().add_subplot(111)
>>> a=axes.get_xticks().tolist()
>>> a[1]='change'
>>> axes.set_xticklabels(a)
[<matplotlib.text.Text object at 0x539aa50>, <matplotlib.text.Text object at 0x53a0c90>, 
<matplotlib.text.Text object at 0x53a73d0>, <matplotlib.text.Text object at 0x53a7a50>, 
<matplotlib.text.Text object at 0x53aa110>, <matplotlib.text.Text object at 0x53aa790>]
>>> plt.show()

và kết quả: nhập mô tả hình ảnh ở đây

và bây giờ nếu bạn kiểm tra _xticklabels, chúng không còn là một bó ''nữa.

>>> [item.get_text() for item in axes.get_xticklabels()]
['0.0', 'change', '1.0', '1.5', '2.0']

Nó hoạt động trong các phiên bản từ 1.1.1rc1đến phiên bản hiện tại 2.0.


Cảm ơn, đây là câu trả lời tôi đang tìm kiếm. Giải pháp sạch nhất IMO; chỉ cần cung cấp set_xticklabelsvới một danh sách hỗn hợp các chuỗi và đánh dấu các đối tượng.
Luke Davis

Xin lưu ý rằng nếu nhãn tick được đặt là ints, điều này sẽ thay đổi chúng thành float. Dễ dàng làm việc xung quanh nhưng đáng chú ý.
Tiếp

Cái này làm việc ( ax.get_xticks().tolist()). Các giải pháp được bình chọn nhiều nhất đã không ( ax.get_xtickslabels()). Bằng cách nào đó, nó không thể trích xuất các nhãn trước khi plt.show()bị loại bỏ, mặc dù tôi đã sử dụng fig.canvas.draw()như đề xuất.
CypherX

FYI, từ các tài liệu matplotlib hiện đại : "pylab không được dùng nữa và việc sử dụng nó bị ngăn cản mạnh mẽ vì ô nhiễm không gian tên. Thay vào đó, hãy sử dụng pyplot."
Nathaniel Jones

17

Đã được một lúc kể từ khi câu hỏi này được hỏi. Cho đến hôm nay ( matplotlib 2.2.2) và sau một số lần đọc và thử nghiệm, tôi nghĩ cách tốt nhất / phù hợp là như sau:

Matplotlib có một module có tên ticker"chứa các lớp để hỗ trợ hoàn toàn có thể cấu hình định vị đánh dấu và định dạng" . Để sửa đổi một đánh dấu cụ thể từ cốt truyện, các công việc sau đây đối với tôi:

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np 

def update_ticks(x, pos):
    if x == 0:
        return 'Mean'
    elif pos == 6:
        return 'pos is 6'
    else:
        return x

data = np.random.normal(0, 1, 1000)
fig, ax = plt.subplots()
ax.hist(data, bins=25, edgecolor='black')
ax.xaxis.set_major_formatter(mticker.FuncFormatter(update_ticks))
plt.show()

Biểu đồ với các giá trị ngẫu nhiên từ một phân phối bình thường

Hãy cẩn thận! xlà giá trị của đánh dấu vàpos là vị trí tương đối của nó theo thứ tự trong trục. Lưu ý rằng poslấy các giá trị bắt đầu 1, không phải 0như bình thường khi lập chỉ mục.


Trong trường hợp của tôi, tôi đã cố gắng định dạng y-axisbiểu đồ với các giá trị phần trăm. mtickercó một lớp khác có tên PercentFormattercó thể thực hiện điều này một cách dễ dàng mà không cần xác định hàm riêng như trước:

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np 

data = np.random.normal(0, 1, 1000)
fig, ax = plt.subplots()
weights = np.ones_like(data) / len(data)
ax.hist(data, bins=25, weights=weights, edgecolor='black')
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1.0, decimals=1))
plt.show()

Biểu đồ với các giá trị ngẫu nhiên từ một phân phối bình thường

Trong trường hợp xmaxnày là giá trị dữ liệu tương ứng với 100%. Tỷ lệ được tính là x / xmax * 100, đó là lý do tại sao chúng tôi sửa chữa xmax=1.0. Ngoài ra, decimalslà số vị trí thập phân để đặt sau điểm.


12

Lớp axes có hàm set_yticklabels cho phép bạn đặt nhãn tick, như vậy:

#ax is the axes instance
group_labels = ['control', 'cold treatment',
             'hot treatment', 'another treatment',
             'the last one']

ax.set_xticklabels(group_labels)

Tôi vẫn đang làm việc tại sao ví dụ của bạn ở trên không hoạt động.


3
Nhưng tôi chỉ muốn thay đổi một nhãn hiệu duy nhất. Thủ thuật trên yêu cầu bạn trích xuất tất cả các nhãn đánh dấu và đặt giá trị mong muốn thành giá trị mới. Nhưng làm thế nào tôi có thể trích xuất các nhãn đánh dấu khi nhãn.get lòng () không trả về gì?
repoman

11

Những công việc này:

import matplotlib.pyplot as plt

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

x1 = [0,1,2,3]
squad = ['Fultz','Embiid','Dario','Simmons']

ax1.set_xticks(x1)
ax1.set_xticklabels(squad, minor=False, rotation=45)

Liên bang


7

Điều này cũng hoạt động trong matplotlib 3:

x1 = [0,1,2,3]
squad = ['Fultz','Embiid','Dario','Simmons']

plt.xticks(x1, squad, rotation=45)

5

Nếu bạn không làm việc với figaxbạn muốn sửa đổi tất cả các nhãn (ví dụ: để chuẩn hóa), bạn có thể làm điều này:

labels, locations = plt.yticks()
plt.yticks(labels, labels/max(labels))

1

Thử cái này :

  fig,axis = plt.subplots(nrows=1,ncols=1,figsize=(13,6),sharex=True)
  axis.set_xticklabels(['0', 'testing', '10000', '20000', '30000'],fontsize=22)

-4

bạn có thể làm:

for k in ax.get_xmajorticklabels():
    if some-condition:
        k.set_color(any_colour_you_like)

draw()

Ai đó có thể giải thích tại sao câu trả lời này bị đánh giá quá thấp?
Hlynur Davíð Hlynsson

@ HlynurDavíðHlynsson Tôi nghĩ rằng nó không thực sự có liên quan đến câu hỏi. Chà, có thể với một số chỉnh sửa ... Vui lòng chỉnh sửa nó, nếu bạn có liên quan đến câu hỏi. ;)
yêu.by.Jesus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.