วิธีสร้างหลายแปลงในหน้าเดียวโดยใช้ matplotlib


92

ฉันเขียนโค้ดที่เปิด 16 ตัวเลขพร้อมกัน ปัจจุบันทั้งหมดเปิดเป็นกราฟแยกกัน ฉันต้องการให้พวกเขาเปิดทั้งหมดในหน้าเดียวกัน ไม่ใช่กราฟเดียวกัน ฉันต้องการ 16 กราฟแยกกันในหน้าเดียว / หน้าต่าง ด้วยเหตุผลบางประการรูปแบบของตัวเลขและค่าเริ่มต้นจะไม่ถือรูปที่ 1 ที่ผ่านมาฉันจำเป็นต้องใช้คำสั่ง subplot หรือไม่? ฉันไม่เข้าใจว่าทำไมฉันต้องทำ แต่คิดไม่ออกว่าจะทำอะไรอีก?

import csv
import scipy.stats
import numpy
import matplotlib.pyplot as plt

for i in range(16):
    plt.figure(i)
    filename= easygui.fileopenbox(msg='Pdf distance 90m contour', title='select file', filetypes=['*.csv'], default='X:\\herring_schools\\')
    alt_file=open(filename)    
    a=[]
    for row in csv.DictReader(alt_file):
        a.append(row['Dist_90m(nmi)'])
    y= numpy.array(a, float)    
    relpdf=scipy.stats.relfreq(y, numbins=7, defaultreallimits=(-10,60))
    bins = numpy.arange(-10,60,10)
    print numpy.sum(relpdf[0])
    print bins
    patches=plt.bar(bins,relpdf[0], width=10, facecolor='black')
    titlename= easygui.enterbox(msg='write graph title', title='', default='', strip=True, image=None, root=None)
    plt.title(titlename)
    plt.ylabel('Probability Density Function')
    plt.xlabel('Distance from 90m Contour Line(nm)')
    plt.ylim([0,1])

plt.show()

คำตอบ:


17

ในการตอบคำถามหลักของคุณคุณต้องใช้คำสั่งsubplot ฉันคิดว่าการเปลี่ยนplt.figure(i)เป็นplt.subplot(4,4,i+1)ควรใช้งานได้


202

คำตอบจากlas3rjockซึ่งเป็นคำตอบที่ OP ยอมรับไม่ถูกต้อง - รหัสไม่ทำงานและเป็นไวยากรณ์ matplotlib ที่ถูกต้อง คำตอบนั้นไม่มีโค้ดที่รันได้และไม่มีข้อมูลหรือคำแนะนำใด ๆ ที่ OP อาจพบว่ามีประโยชน์ในการเขียนโค้ดของตนเองเพื่อแก้ปัญหาใน OP

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

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

plt.figure () (ซึ่งโดยปกติแล้ว plt หรือ PLT จะเป็นไลบรารี pyplotของ matplotlib ที่อิมพอร์ตและรีบาวด์เป็นตัวแปรส่วนกลาง plt หรือบางครั้งก็เป็น PLT เช่น:

from matplotlib import pyplot as PLT

fig = PLT.figure()

บรรทัดด้านบนสร้างอินสแตนซ์รูป matplotlib เมธอดadd_subplotของออบเจ็กต์นี้จะถูกเรียกใช้สำหรับทุก ๆ หน้าต่างการลงจุด (นึกถึงแกน x & y ที่ประกอบด้วยพล็อตย่อยเดียวอย่างไม่เป็นทางการ) คุณสร้าง (ไม่ว่าจะเป็นเพียงหนึ่งหน้าหรือหลายหน้า) เช่นนั้น

fig.add_subplot(111)

ไวยากรณ์นี้เทียบเท่ากับ

fig.add_subplot(1,1,1)

เลือกสิ่งที่เหมาะสมกับคุณ

ด้านล่างนี้ฉันได้ระบุรหัสเพื่อลงจุดสองพล็อตบนหน้าหนึ่งอยู่เหนืออีกอันหนึ่ง การจัดรูปแบบจะทำผ่านการโต้แย้งส่งผ่านไปยังadd_subplot สังเกตว่าอาร์กิวเมนต์คือ ( 211 ) สำหรับพล็อตแรกและ ( 212 ) สำหรับวินาที

from matplotlib import pyplot as PLT

fig = PLT.figure()

ax1 = fig.add_subplot(211)
ax1.plot([(1, 2), (3, 4)], [(4, 3), (2, 3)])

ax2 = fig.add_subplot(212)
ax2.plot([(7, 2), (5, 3)], [(1, 6), (9, 5)])

PLT.show()

อาร์กิวเมนต์ทั้งสองนี้เป็นข้อกำหนดที่สมบูรณ์สำหรับการวางหน้าต่างพล็อตตามลำดับบนเพจอย่างถูกต้อง

211 (ซึ่งอีกครั้งสามารถเขียนในรูปแบบ 3 ทูเพิลได้เช่นกัน (2,1,1) หมายถึงสองแถวและหนึ่งคอลัมน์ของหน้าต่างพล็อตตัวเลขที่สามระบุลำดับของหน้าต่างพล็อตย่อยนั้นโดยสัมพันธ์กับหน้าต่างพล็อตย่อยอื่น ๆ - ในกรณีนี้นี่คือพล็อตแรก (ซึ่งวางไว้ในแถวที่ 1) ดังนั้นพล็อตหมายเลข 1 แถว 1 col 1

อาร์กิวเมนต์ส่งผ่านไปยังการเรียกครั้งที่สองเพื่อadd_subplotซึ่งแตกต่างจากตัวเลขแรกเท่านั้นโดยตัวเลขต่อท้าย (a 2 แทนที่จะเป็น 1 เนื่องจากพล็อตนี้เป็นพล็อตที่สอง (แถว 2, col 1)

ตัวอย่างที่มีพล็อตเพิ่มเติม: ถ้าคุณต้องการสี่พล็อตบนเพจในการกำหนดค่าเมทริกซ์ 2x2 คุณจะเรียกเมธอด add_subplot สี่ครั้งโดยส่งผ่านอาร์กิวเมนต์ทั้งสี่นี้ (221), (222), (223) และ ( 224) เพื่อสร้างสี่พล็อตบนหน้าที่ 10, 2, 8 และ 4 นาฬิกาตามลำดับและตามลำดับ

โปรดสังเกตว่าอาร์กิวเมนต์ทั้งสี่มีสองตะกั่ว 2 ซึ่งเข้ารหัสการกำหนดค่า 2 x 2 นั่นคือสองแถวและสองคอลัมน์

หลักที่สาม (ขวาสุด) ในแต่ละอาร์กิวเมนต์ทั้งสี่จะเข้ารหัสลำดับของหน้าต่างพล็อตนั้นในเมทริกซ์ 2 x 2 นั่นคือแถว 1 col 1 (1) แถว 1 col 2 (2) แถว 2 col 1 (3) แถว 2 col 2 (4)


1
add_subplot สามารถใช้อาร์กิวเมนต์จำนวนเต็มเดียวสำหรับพล็อตย่อยจำนวนน้อย แต่เมื่อคุณต้องการมากกว่า 9 พล็อตย่อยคุณควรใช้เวอร์ชันจากคำตอบอื่นซึ่งใช้อาร์กิวเมนต์จำนวนเต็ม 3 อาร์กิวเมนต์แยกกัน
user1244215

1
ใช้fig.add_axes(rect)แทนได้add_subplotไหม
Alcott

16
PLTเหรอ? ไม่เคยเห็นว่าถูกใช้มาก่อน
Darshan Chaudhary

3
ย่อหน้าแรกของคุณตรงนี้ไม่เป็นความจริงเนื่องจากคุณสามารถตรวจสอบได้โดยการเรียกใช้for i in range(16): plt.subplot(4, 4, i+1)และสังเกตว่าไม่มีข้อผิดพลาดทางไวยากรณ์ คำตอบคือได้รับการยอมรับเพราะอาจทำในสิ่งที่ OP ต้องการ
chthonicdaemon

3
นี่เป็นทางออกที่ดี แต่ถ้าอยากใช้ตัวแปรเดียวเพื่อวนซ้ำทำอย่างไร?
Pengju Zhao

83

เนื่องจากคำถามนี้มาจาก 4 ปีที่แล้วมีการใช้สิ่งใหม่ ๆ และในหมู่พวกเขามีฟังก์ชั่นใหม่plt.subplotsที่สะดวกมาก :

fig, axes = plot.subplots(nrows=2, ncols=3, sharex=True, sharey=True)

ที่axesเป็นnumpy.ndarrayของวัตถุ AxesSubplot [i,j]ทำให้มันง่ายมากที่จะไปผ่านย่อยที่แตกต่างกันเพียงแค่ใช้ดัชนีอาร์เรย์


วิธีนี้ใช้ได้กับกรณีที่ฉันจำเป็นต้องใช้ matplotlib API เท่านั้นหรือไม่ (เนื่องจากจอแสดงผลไม่พร้อมใช้งานและสิ่งตลกอื่น ๆ )
eudoxos

2
@eudoxos ใช่คุณควรสร้างพล็อตย่อยเช่นนี้เพื่อพิมพ์กราฟิกหลาย ๆ หน้าในหน้าเดียวโดยไม่จำเป็นต้องแสดงสิ่งที่กำลังทำ
Saullo GP Castro

12

งานนี้ยัง:

for i in range(19):
    plt.subplot(5,4,i+1) 

แปลงกราฟทั้งหมด 19 กราฟในหนึ่งหน้า รูปแบบคือ 5 ลงและ 4 ข้าม ..


4

คำตอบของ @doug & FS เป็นคำตอบที่ดีมาก ฉันต้องการแบ่งปันวิธีแก้ปัญหาสำหรับการทำซ้ำบน pandas.dataframe

import pandas as pd
df=pd.DataFrame([[1, 2], [3, 4], [4, 3], [2, 3]])
fig = plt.figure(figsize=(14,8))
for i in df.columns:
    ax=plt.subplot(2,1,i+1) 
    df[[i]].plot(ax=ax)
    print(i)
plt.show()

หาก data frame ของคุณตั้งชื่อคอลัมน์คุณจะต้องใช้สิ่งต่างๆเช่นfor i,col in enumerate(df.columns):
drevicko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.