ทำไมตัวอย่างมากมายจึงใช้ `fig, ax = plt.subplots ()` ใน Matplotlib / pyplot / python


267

ฉันกำลังเรียนรู้ที่จะใช้matplotlibโดยการศึกษาตัวอย่างและตัวอย่างมากมายดูเหมือนจะมีบรรทัดดังต่อไปนี้ก่อนที่จะสร้างพล็อตเดียว ...

fig, ax = plt.subplots()

นี่คือตัวอย่างบางส่วน...

ฉันเห็นว่าฟังก์ชั่นนี้ใช้บ่อยมากแม้ว่าตัวอย่างจะพยายามสร้างแผนภูมิเดียวเท่านั้น มีข้อได้เปรียบอื่น ๆ อีกไหม? การสาธิตอย่างเป็นทางการสำหรับsubplots()ใช้f, ax = subplotsเมื่อสร้างแผนภูมิเดียวและจะใช้อ้างอิงขวานหลังจากนั้นเท่านั้น นี่คือรหัสที่พวกเขาใช้

# Just a figure and one subplot
f, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Simple plot')

11
มันสั้นกระชับและคุณได้รับการอ้างอิงทั้งสองรูปและแกนในขั้นตอนเดียว มัน pythonic เพราะมันสวยงาม :)
เต็มอิ่ม

คำตอบ:


325

plt.subplots()เป็นฟังก์ชันที่คืนค่า tuple ที่มีวัตถุรูปและแกน ดังนั้นเมื่อใช้fig, ax = plt.subplots()คุณแกะ tuple นี้ลงในตัวแปรและfig axการมีfigประโยชน์ถ้าคุณต้องการเปลี่ยนแอตทริบิวต์ระดับรูปหรือบันทึกรูปภาพเป็นไฟล์รูปภาพในภายหลัง (เช่นด้วยfig.savefig('yourfilename.png')) แน่นอนคุณไม่จำเป็นต้องใช้วัตถุรูปที่ส่งคืน แต่หลาย ๆ คนใช้มันในภายหลังดังนั้นจึงเป็นเรื่องปกติที่จะเห็น นอกจากนี้วัตถุแกนทั้งหมด (วัตถุที่มีวิธีการพล็อต) มีวัตถุรูปหลักอยู่แล้วดังนั้น:

fig, ax = plt.subplots()

กระชับกว่านี้:

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

8
คำอธิบายที่ดีมาก นี่คือเอกสารเกี่ยวกับมัน - matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplots
bretcj7

2
ทำไมเราใช้ 111 เป็นพารามิเตอร์ในแผนย่อยเสมอ?
Priyansh

@Priyansh เพราะมันได้รับมาจากไวยากรณ์ Matlab
pcko1

@Priyansh ไม่เสมอไป หากคุณต้องการกราฟ 4 ตัวคุณสามารถax11, ax12, ax21, ax22ใช้fig.add_subplot(221)(หรือ 222, 223, 224 ตามลำดับ)
Guimoute

49

เป็นเพียงอาหารเสริมที่นี่

คำถามต่อไปนี้คือสิ่งที่ถ้าฉันต้องการย่อยมากขึ้นในรูป?

ดังที่ได้กล่าวไว้ใน Doc เราสามารถใช้fig = plt.subplots(nrows=2, ncols=2)เพื่อตั้งกลุ่มย่อยที่มีกริด (2,2) ในวัตถุรูปหนึ่ง

ถ้าอย่างนั้นเราก็รู้ว่าfig, ax = plt.subplots()ผลตอบแทนเป็น tuple เรามาลองfig, ax1, ax2, ax3, ax4 = plt.subplots(nrows=2, ncols=2)ก่อน

ValueError: not enough values to unpack (expected 4, got 2)

มันทำให้เกิดข้อผิดพลาด แต่ไม่ต้องกังวลเพราะตอนนี้เราเห็นว่าplt.subplots()จริง ๆ แล้วคืนค่า tuple ด้วยสององค์ประกอบ อันที่หนึ่งจะต้องเป็นวัตถุรูปและอีกอันหนึ่งควรเป็นกลุ่มของวัตถุย่อย

ดังนั้นลองอีกครั้ง:

fig, [[ax1, ax2], [ax3, ax4]] = plt.subplots(nrows=2, ncols=2)

และตรวจสอบประเภท:

type(fig) #<class 'matplotlib.figure.Figure'>
type(ax1) #<class 'matplotlib.axes._subplots.AxesSubplot'>

แน่นอนถ้าคุณใช้พารามิเตอร์เป็น (nrows = 1, ncols = 4) ดังนั้นรูปแบบควรเป็น:

fig, [ax1, ax2, ax3, ax4] = plt.subplots(nrows=1, ncols=4)

ดังนั้นอย่าลืมสร้างโครงสร้างของรายการให้เหมือนกับตารางย่อยที่เราตั้งไว้ในรูป

หวังว่านี่จะเป็นประโยชน์สำหรับคุณ


2
อย่าลืมที่จะเพิ่ม plt.tight_layout () ถ้าแผนการย่อยของคุณมีชื่อ
gota

12
ถ้าคุณมีแผนการย่อยมากมาย มันง่ายที่จะทำมันด้วยวิธีนี้: และfig, axes = plt.subplots(nrows=10, ncols=3) axes = axes.flatten()ตอนนี้คุณสามารถดูแต่ละแผนโดยดัชนี: axes[0], axes[1]...
กีโยม

ถ้าฉันต้องการหนึ่งใน subplots เหล่านั้นเพื่อขยาย cols หรือแถวหลายแถว ใช้คำสั่งย่อยได้หรือไม่
gota

1
@BallpointBen ฉันไม่แน่ใจว่าใช้งานได้ถ้าnrows=1เช่นนั้นaxesจะถูกส่งกลับแบนที่มีความยาวเท่ากับncols
Ben

1
@BallpointBen เพิ่งรู้ว่าคุณสามารถแก้ไขปัญหานี้ได้โดยทำดังนี้:fig, axes = plt.subplots(nrows=1, ncols=3, squeeze=False)
Ben

15

ในฐานะที่เป็นส่วนเสริมของคำถามและคำตอบข้างต้นยังมีความแตกต่างที่สำคัญระหว่างplt.subplots()และplt.subplot()ให้สังเกตว่าการขาดหายไป's'ในตอนท้าย

หนึ่งสามารถใช้plt.subplots()เพื่อทำให้ย่อยทั้งหมดของพวกเขาในครั้งเดียวและมันจะส่งกลับรูปและแกน รูปสามารถเข้าใจได้ว่าเป็นผืนผ้าใบที่คุณวาดภาพร่างของคุณ

# create a subplot with 2 rows and 1 columns
fig, ax = plt.subplots(2,1)

ในขณะที่คุณสามารถใช้plt.subplot()หากคุณต้องการเพิ่มแผนการย่อยแยกต่างหาก ส่งคืนแกนของแผนย่อยเดียวเท่านั้น

fig = plt.figure() # create the canvas for plotting
ax1 = plt.subplot(2,1,1) 
# (2,1,1) indicates total number of rows, columns, and figure number respectively
ax2 = plt.subplot(2,1,2)

อย่างไรก็ตามplt.subplots()เป็นที่ต้องการเนื่องจากจะช่วยให้คุณมีตัวเลือกที่ง่ายขึ้นในการปรับแต่งทั้งร่างของคุณโดยตรง

# for example, sharing x-axis, y-axis for all subplots can be specified at once
fig, ax = plt.subplots(2,2, sharex=True, sharey=True)

แกนที่ใช้ร่วมกัน ในขณะที่ด้วยplt.subplot()หนึ่งจะต้องระบุเป็นรายบุคคลสำหรับแต่ละแกนซึ่งอาจกลายเป็นยุ่งยาก


1
บรรทัดโค้ดของคุณax3 = plt.subplot(2,1,3) ไม่ทำงานเพราะเป็น 2 ต่อ 1 ซึ่งมีเพียง 2 กราฟ
เมฆโช

1
ขอบคุณแก้ไขมัน จำเป็นต้องมีการเปลี่ยนแปลงอื่นในการบล็อกโค้ดครั้งสุดท้าย
Light_B

3

นอกเหนือจากคำตอบข้างต้นคุณสามารถตรวจสอบประเภทของวัตถุที่ใช้type(plt.subplots())ซึ่งคืน tuple ในทางtype(plt.subplot())กลับกันmatplotlib.axes._subplots.AxesSubplotซึ่งคุณไม่สามารถแยกบรรจุ


4
ยินดีต้อนรับสู่ Stack Overflow! นี่เป็นความคิดเห็นจริงๆไม่ใช่คำตอบ กับบิตตัวแทนมากขึ้นคุณจะสามารถที่จะแสดงความคิดเห็น ขอบคุณ!
Miroslav Glamuzina
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.