แก้ไขข้อความเลเบลเห็บ


216

ฉันต้องการแก้ไขป้ายกำกับที่เลือกไม่กี่ตัวในพล็อต

ตัวอย่างเช่นถ้าฉัน:

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

ขนาดตัวอักษรและการวางแนวของฉลากเห็บมีการเปลี่ยนแปลง

อย่างไรก็ตามหากลอง:

label.set_text('Foo')

ไม่มีการแก้ไขฉลากเลเบล นอกจากนี้ถ้าฉันทำ:

print label.get_text()

ไม่มีการพิมพ์อะไรเลย

นี่คือความแปลกประหลาดมากขึ้น เมื่อฉันลองทำสิ่งนี้:

 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()

มีการพิมพ์เฉพาะสตริงว่าง แต่พล็อตมีเครื่องหมายที่ระบุว่า '0.0', '0.5', '1.0', '1.5' และ '2.0'


คุณสามารถระบุพล็อตที่คุณใช้เพื่อรับฉลากได้หรือไม่?
Claudio

คุณได้รับป้ายกำกับว่างเปล่าเนื่องจากคุณยังไม่ได้วาดผืนผ้าใบ หากคุณโทรdraw()มาก่อนพยายามพิมพ์ฉลากคุณจะได้รับสิ่งที่คุณคาดหวัง การตั้งค่าป้ายกำกับแต่ละรายการนั้นเป็นเรื่องยากที่จะสัมผัส (เกิดอะไรขึ้นคือตัวระบุเห็บและตัวจัดรูปแบบไม่ได้ถูกรีเซ็ตและมันจะแทนที่สิ่งต่าง ๆ เมื่อคุณset_text) ฉันจะเพิ่มตัวอย่างเล็กน้อยถ้ามีคนไม่ชนะฉัน ฉันต้องขึ้นรถบัสในขณะนี้
Joe Kington

@ JoeKington: เยี่ยมมาก! รอคอยที่จะเห็นการแก้ไขของคุณ
repoman

@repoman - ดูเหมือนว่าฉันจะพูดช้าเกินไป สิ่งที่ฉันมีอยู่ในใจทำงานได้กับ matplotlib รุ่นเก่า แต่ไม่ใช่รุ่นล่าสุด ฉันต้องขุดอีกหน่อย ที่ได้รับการกล่าวว่าสิ่งนี้ไม่ควรซับซ้อนเท่าที่เป็นอยู่ ...
Kington Joe

คำตอบ:


298

Caveat: ยกเว้นว่า ticklabels ถูกตั้งค่าเป็นสตริงอยู่แล้ว (ตามปกติในกรณีเช่น boxplot) สิ่งนี้จะไม่ทำงานกับ matplotlib รุ่นใหม่กว่า 1.1.0ใหม่กว่าใด หากคุณกำลังทำงานจากหัวหน้า GitHub ปัจจุบันนี้จะไม่ทำงาน ฉันไม่แน่ใจว่าปัญหาคืออะไร ... มันอาจเป็นการเปลี่ยนแปลงที่ไม่ได้ตั้งใจหรือมันอาจจะไม่ ...

โดยปกติคุณจะทำบางสิ่งตามบรรทัดเหล่านี้:

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()

ป้อนคำอธิบายรูปภาพที่นี่

เพื่อให้เข้าใจถึงเหตุผลที่คุณต้องกระโดดผ่านห่วงจำนวนมากคุณต้องเข้าใจอีกเล็กน้อยเกี่ยวกับวิธีการจัดโครงสร้างของ matplotlib

Matplotlib จงใจหลีกเลี่ยงการทำเครื่องหมาย "คงที่" ของเห็บ ฯลฯ เว้นแต่จะมีการแจ้งให้ทราบอย่างชัดเจน สมมติฐานคือคุณจะต้องการโต้ตอบกับพล็อตและขอบเขตของพล็อต, ติ๊ก, ticklabels และอื่น ๆ จะเปลี่ยนแปลงตลอดเวลา

ดังนั้นคุณไม่สามารถตั้งค่าข้อความของป้ายกำกับที่ระบุ โดยค่าเริ่มต้นจะถูกตั้งค่าใหม่โดยตัวระบุตำแหน่งของแกนและตัวจัดรูปแบบทุกครั้งที่วาดพล็อต

อย่างไรก็ตามหาก Locators and Formatters ถูกตั้งค่าเป็นแบบสแตติก ( FixedLocatorและFixedFormatterตามลำดับ) ป้ายกำกับจะยังคงเหมือนเดิม

นี่คือสิ่งที่set_*ticklabelsหรือax.*axis.set_ticklabelsไม่

หวังว่าจะทำให้ชัดเจนขึ้นเล็กน้อยว่าทำไมการเปลี่ยนฉลากติ๊กแต่ละรายการนั้นค่อนข้างซับซ้อน

บ่อยครั้งที่สิ่งที่คุณต้องการทำจริง ๆ เพียงแค่ใส่คำอธิบายประกอบตำแหน่งที่แน่นอน ในกรณีนี้ให้ดูannotateแทน


10
ดูเหมือนจะไม่ทำงานกับเวอร์ชันปัจจุบัน (1.20)!
Andrew Jaffe

1
หาก ticklablab ถูกตั้งค่าเป็นสตริงเช่นเดียวกับ boxplot แสดงว่ายังคงใช้งานได้ สิ่งนี้อาจเห็นได้ชัด แต่เนื่องจากบรรทัดแรกของคำตอบคือมันไม่ทำงานกับเวอร์ชัน matplotlib ที่ใหม่กว่าผู้ใช้อาจข้ามไปเลย (ฉันทำตอนแรก) อาจพูดถึงเรื่องนี้ในเวลาสั้น ๆ
joelostblom

2
ฉันคิดว่าคุณสามารถย่อให้เป็นplt.gca () ได้ set_xticklabels (ป้ายกำกับ)
alexey

จะทำอย่างไรถ้าฉันต้องการให้น้ำหนักตัวอักษรของ "การทดสอบ" เป็นboldในขณะที่คนอื่นใช้ตัวอักษรน้ำหนักเบาของ "แสง" มีวิธีทำหรือไม่?
steven

1
สำหรับผู้ที่ใช้สิ่งนี้ในสมุดบันทึก jupyter อาจได้รับประโยชน์จากการสังเกตว่าfig.canvas.draw()สำคัญ
wander95

96

ท่านสามารถทำได้ด้วยpylabและxticks

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


นี่เป็นวิธีแก้ปัญหาที่ง่ายและทำงานได้กับ pyplot 1.5.1 สิ่งนี้ควรถูก upvoted
wordsmith

แม้ว่าคำถามจะไม่ขอสิ่งนี้ แต่ฉันขอขอบคุณตัวอย่างนี้ช่วยให้คุณสามารถกำหนดตำแหน่งของเห็บได้ในเวลาเดียวกันกับการปรับเปลี่ยนป้ายกำกับของพวกเขา
eclark

จากเอกสาร matplotlib ที่ทันสมัย: "pylab เลิกใช้แล้วและมีการใช้งานอย่างมากเนื่องจากมีมลภาวะเนมสเปซใช้ pyplot แทน"
นาธาเนียลโจนส์

93

ในเวอร์ชันที่ใหม่กว่าของmatplotlibถ้าคุณไม่ได้ตั้งค่าเลเบลเห็บด้วยstrค่าจำนวนมากพวกมันจะเป็น''ค่าเริ่มต้น (และเมื่อพล็อตถูกวาด รู้ว่าเพื่อให้ได้ผลลัพธ์ที่คุณต้องการจะต้องมีดังนี้:

>>> 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()

และผลลัพธ์: ป้อนคำอธิบายรูปภาพที่นี่

และตอนนี้ถ้าคุณตรวจสอบ _xticklabels''พวกเขาจะไม่พวงของ

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

มันทำงานได้ในรุ่นจากเวอร์ชันปัจจุบัน1.1.1rc12.0


ขอบคุณนี่คือคำตอบที่ฉันต้องการ วิธีการแก้ปัญหาที่สะอาดที่สุด IMO; เพียงจัดหาset_xticklabelsรายการสตริงและทำเครื่องหมายวัตถุผสม
ลุคเดวิส

โปรดทราบว่าหากมีการตั้งค่าป้ายกำกับเห็บเป็น ints สิ่งนี้จะเปลี่ยนเป็นลอย ทำงานได้อย่างง่ายดาย แต่ไม่ควรพลาด
ApproachDarknessFish

อันนี้ใช้ได้ ( ax.get_xticks().tolist()) วิธีแก้ปัญหาที่โหวตมากที่สุดไม่ได้ ( ax.get_xtickslabels()) อย่างใดมันก็ไม่สามารถแยกฉลากก่อนที่จะplt.show()ได้รับการยกเว้นแม้ว่าฉันจะใช้fig.canvas.draw()ตามที่แนะนำ
CypherX

FYI จากเอกสาร matplotlib ที่ทันสมัย: "pylab เลิกใช้แล้วและการใช้งานนั้นไม่ได้รับการสนับสนุนอย่างมากเนื่องจากมลภาวะเนมสเปซใช้ pyplot แทน"
นาธาเนียลโจนส์

17

คำถามนี้ถูกถามมานานแล้ว ณ วันนี้ ( matplotlib 2.2.2) และหลังจากการอ่านและการทดลองฉันคิดว่าวิธีที่ดีที่สุด / เหมาะสมคือ:

Matplotlib มีโมดูลที่มีชื่อtickerว่า"มีคลาสที่ให้การสนับสนุนตำแหน่งเห็บกำหนดอย่างสมบูรณ์และการจัดรูปแบบ" หากต้องการแก้ไขเห็บเฉพาะจากพล็อต

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()

ฮิสโตแกรมที่มีค่าสุ่มจากการแจกแจงแบบปกติ

ข้อแม้! xคือค่าของเห็บและposเป็นตำแหน่งสัมพัทธ์ตามลำดับในแกน ขอให้สังเกตว่าposใช้ค่าเริ่มต้นใน1ไม่ได้0ตามปกติเมื่อจัดทำดัชนี


ในกรณีของฉันฉันพยายามจัดรูปแบบy-axisฮิสโตแกรมด้วยค่าเปอร์เซ็นต์ mtickerมีคลาสอีกชื่อPercentFormatterที่สามารถทำสิ่งนี้ได้อย่างง่ายดายโดยไม่จำเป็นต้องกำหนดฟังก์ชั่นแยกต่างหากเหมือนเมื่อก่อน:

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()

ฮิสโตแกรมที่มีค่าสุ่มจากการแจกแจงแบบปกติ

ในกรณีนี้xmaxคือค่าข้อมูลที่สอดคล้องกับ 100% เปอร์เซ็นต์การคำนวณเป็นที่ว่าทำไมเราจะแก้ไขปัญหาx / xmax * 100 xmax=1.0ยังdecimalsเป็นจำนวนตำแหน่งทศนิยมที่จะวางหลังจากจุด


12

คลาส axes มีฟังก์ชั่นset_yticklabelsซึ่งช่วยให้คุณตั้งค่าเลเบลเห็บเช่น:

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

ax.set_xticklabels(group_labels)

ฉันยังคงทำงานเพื่อดูว่าทำไมตัวอย่างของคุณด้านบนใช้งานไม่ได้


3
แต่ฉันต้องการแก้ไขป้ายกำกับเดียว เคล็ดลับข้างต้นต้องการให้คุณแยกป้ายกำกับการทำเครื่องหมายทั้งหมดและตั้งค่าที่ต้องการเป็นค่าใหม่ แต่ฉันจะแยกป้ายกำกับเห็บได้อย่างไรเมื่อ label.get_text () ไม่ส่งคืนอะไรเลย
repoman

11

งานนี้:

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)

เอฟบีไอ


7

สิ่งนี้ยังใช้งานได้ใน matplotlib 3:

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

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

5

หากคุณไม่ทำงานด้วยfigและaxและคุณต้องการแก้ไขป้ายกำกับทั้งหมด (เช่นสำหรับการทำให้เป็นมาตรฐาน) คุณสามารถทำได้:

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

1

ลองสิ่งนี้:

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

-4

คุณทำได้:

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

draw()

ใครสามารถอธิบายได้ว่าทำไมคำตอบนี้จึงลดลงอย่างมาก
Hlynur Davíð Hlynsson

@ HlynurDavíðHlynssonฉันคิดว่ามันไม่มีอะไรเกี่ยวข้องกับคำถาม อาจจะมีการแก้ไขบางอย่าง ... โปรดแก้ไขถ้าคุณได้เกี่ยวข้องกับคำถาม ;)
Loved.by.Jesus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.