Tags:
Forums: 

ปรกติผมทำงานคำนวณบน matlab แล้วผลที่ได้ก็แสดงออกมาเป็นกราฟได้เลย แต่ว่า "มันไม่สวย" เลยจะพล็อตด้วย matplotlib แต่ว่าตัวอย่างที่เคยเห็นที่พล็อตนั้น เป็นอาร์เรย์ 1 มิติ แต่งานที่ผมใช้คำนวณมันมากกว่า 1 มิติ เลยอยากขอไอเดียหน่อยครับว่าจะทำอย่างไร

ตัวอย่างใน matlab ที่ผมใช้เช่น

freq = [10 20 30 40 50 60];
attenuation = [[0.1 0.2 0.3 0.4 0.5 0.6]; [0.2 0.4 0.6 0.8 1.0 1.2]];
loglog(freq,attenuation);

ผลที่ได้มันก็จะออกมาเป็นกราฟสองเส้นเส้นแรกเป็นของแถวที่ 1 ของตัวแปร attenuation เส้นที่สองเป็นของแถวที่สอง โดยแกน x เป็น freq แกน y เป็น attenuation

ทีนี้พอผมอยากจะพล็อตด้วย python + numpy + matplotlib นี่ผมจะต้องทำอย่างไรบ้างครับ ปรกติถ้าขอมูลไม่เยอะมากผมก็จะพล็อตโดยแยก attenuation ออกเป็น array ย่อย เช่น

from numpy import *
from pylab import *

freq = [10, 20, 30, 40, 50, 60]
attenuation1 = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
attenuation2 = [0.2, 0.4, 0.6, 0.8, 1.0, 1.2]

loglog(freq,attenuation1, freq,attenuation2)
show()

ข้างบนนี้ค่า attenuation มันมีแค่ 2 แถว แต่งานที่ผมคำนวณมันมีประมาณร้อยกว่าค่า ถ้าจะให้แยกก็คงเสียเวลาไม่น้อย ผมมีพื้นฐาน python ไม่ค่อยมากพึ่งจะเริ่มศึกษา คิดว่ามันน่าจะเกี่ยวกับ for loop แต่พยายามมาหลายวันแล้วยังคิดไม่ตก เลยอยากรบกวนผู้รู้ช่วยแนะให้ไอเดียหน่อยครับ

Get latest news from Blognone
By: nitipit
Android
on 27 November 2010 - 00:48 #235659

คิดว่าน่าจะใช้วิธีจาก Special Arugument-Matching Modes ของ python ครับ

matplotlib.pyplot.loglog(*args, **kwargs)
def ข้างต้นนี้ เป็นการประกาศให้ จับ arguments ที่เข้ามาทั้งหมดเป็น tuple ไว้ใน args ครับ (kwargs ขอไม่พูดถึงละกันนะครับ ^^)
วิธีการใส่ arguments ลงใน loglog() นี้ จะเป็น loglog(x1,y1,x2,y2,x3,y3,...)
ซึ่งในการเรียก def ที่มีการรับค่า args แบบนี้ สามารถใส่ array ไปแล้วให้มัน match เอาเองได้ครับ วิธีก็คือ
1. สร้าง array มาตัวนึง แบบนี้ครับ (ตรงนี้อาจใช้วิธี for loop สร้างเอาได้)

data = [freq1,att1,freq2,att2,freq3,att3,freq4,att4]

2. เรียก loglog() นั้นขึ้นมาทำงาน แล้วใส่ args ไป แบบนี้ครับ

loglog(*data)

สังเกตว่าตัว argument จะใส่ * เข้าไปข้างหน้าหนึ่งตัว ซึ่งเป็น syntax เพื่อบอกให้ทราบว่า จะต้องแยกข้อมูลจาก tuple หรือ list (array ในภาษาอื่น) ที่ส่งไปก่อน แล้วทำการ match ต่อไปครับ

ลองดูนะครับ อันนี้เป็นวิธีนึงในการรับส่งค่าของ python ที่ใช้กันทั่วไปครับ ซึ่งทำให้การรับส่ง arguments ของ def มีความยืดหยุ่นมาก

ไม่แน่ใจว่าตอบถูกรึเปล่า แต่เท่าที่คิดดูผู้ถามน่าจะมีปัญหาว่า จะเอา for loop มาใช้กับการใส่ args ลงไปใน def ได้ยังไง ซึ่งผมคิดว่าต้องใช้วิธีนี้แทนครับ

By: boonkhao
ContributoriPhoneBlackberryUbuntu
on 27 November 2010 - 21:22 #235830
boonkhao's picture

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

from numpy import *
from pylab import *
import numpy as np

freq = [10, 20, 30, 40, 50, 60]
attenuation = np.array([[0.1, 0.2, 0.3, 0.4, 0.5, 0.6], [0.2, 0.4, 0.6, 0.8, 1.0, 1.2]])

i = range(2) # 2 is number of row

for i in range(2):
loglog(freq,attenuation[i][:])

show()

แต่ตอนนี้ขอให้ได้กราฟออกมาก่อน เดี๋ยวส่งงานไม่ทัน -.-" ยังไงก็ขอขอบคุณคุณ nitipit ด้วยครับ