วันอังคารที่ 16 เมษายน พ.ศ. 2556

การแสดง Mesh Plot สามมิติด้วย QtiPlot

ที่มาที่ไป
ในช่วงสามสี่เดือนที่ผ่านมามีภาระกิจเกี่ยวกับงานวิจัยอยู่ (กับเขาบ้าง -- และถูกขัดจังหวะตลอด) กล่าวโดยสังเขปงานวิจัยชิ้นนี้จะทำการวิเคราะห์สัญญาณเสียงแคนโดยใช้ Time-Frequency Analysis แบบ Modal Distribution การวิเคราะห์ทั้งหมดผมทำโดยใช้ Octave ผลการวิเคราะห์จะได้เมตริกซ์ M ซึ่งก็คือเมตริกซ์ Modal Distribution ที่แถวคือแกนความถี่และหลักคือแกนเวลา

ปัญหาของการใช้ Octave ก็คือผลการวิเคราะห์ซึ่งสามารถแสดงผลได้โดยใช้ Mesh Plot ด้วยคำสั่ง
>mesh(M);
จะใช้เวลาในการสร้างรูปนานมาก เนื่องจากเมตริกซ์ M โดยปกติแล้วจะมีขนาดใหญ่ นอกจากนี้แม้ว่าเราจะอดทนพอที่จะรอจนกว่า Octave จะพล๊อตให้เราเสร็จ พอเราจะวิเคราะห์เมชเราก็มักจะหมุนเมชไปมาเสมอ ๆ ซึ่งคำสั่ง mesh ของ Octave จะตอบสนองช้ามากจนไม่สามารถจะวิเคราะห์อะไรได้

ผมก็เลยลองค้นดูว่าใน Debian Repository จะมีอะไรให้ใช้บ้าง พบ QtiPlot ที่คิดว่าน่าจะใช้ได้ครับ การติดตั้งผมใช้ Synaptic ในการติดตั้งจึงจะไม่ลงรายละเอียด

QtiPlot ทำอะไรได้บ้าง? น่าจะหลายอย่างอยู่ แต่ที่ผมได้ทดลองใช้ด้วยตนเองก็คือ
  • พล๊อตกราฟ 2 มิติได้ โดยเราจะต้องเตรียมข้อมูลให้อยู่ในรูปตาราง เราสามารถกำหนดได้ว่าข้อมูลหลักไหนบ้างที่จะอยู่ในแกน x และข้อมูลหลักไหนบ้างที่จะอยู่ในแกน y
  • พล๊อตกราฟ 3 มิติได้ โดยเราจะต้องเตรียมข้อมูลให้อยู่ในรูปของเมตริกซ์ กล่าวคือให้แถวหมายถึงแกน x ให้หลักหมายถึงแกน y และข้อมูลในเซลต่าง ๆ ก็คือแกน z
  • กำหนดสี เส้น ฉลาก ชื่อแกน แบบอักษร ฯลฯ ได้
  • ส่งออกกราฟได้หลายรูปแบบ ที่ผมใช้ก็มี EPS และ PNG ครับ
ฟังคุณสมบัติมาพอสมควร ลองมาดูวิธีใช้ดูบ้างนะครับ

การพล๊อตกราฟ 2 มิติด้วยข้อมูลจาก Octave
QtiPlot รับข้อมูลในรูปแบบของไฟล์ข้อความด้วย เราจึงใช้วิธีบันทึก (Save) ข้อมูลเมตริกซ์จาก Octave ในรูปของไฟล์ข้อความครับ
  1. สมมติว่าเรามีข้อมูลที่จะอยู่ในแกน x ชื่อว่า V และข้อมูลที่จะอยู่ในแกน y ชื่อว่า I เราจะจัดให้ V และ I เป็นคอลัมน์เวคเตอร์ที่มีความยาวเท่ากัน จากนั้นเก็บข้อมูลทั้งสองนี้ลงในเมตริกซ์ตัวหนึ่ง สมมติให้ชื่อเป็น Data 
  2. จากนั้นเราก็บันทึก Data ลงในแฟ้มชื่อ Data.txt โดยใช้คำสั่ง save ของ Octave ซึ่งเราจะใช้คำสั่ง Octave ดังนี้ครับ
> % Prepare testing data
> V = [0:0.1:1';
> I = 0.0005*exp(V/0.2);
> % Prepare data for QtiPlot 
> Data = [V I];
> save -ascii Data.txt Data
เท่านี้ก็เตรียมข้อมูลเสร็จแล้ว ที่ฝั่ง QtoPlot เราก็ Import ข้อมูลเข้าได้ทางเมนู File -> Import -> Import Ascii ได้เลย ในหน้าต่างที่ใช้ Import ข้อมูลก็จะมีตัวเลือกต่าง ๆ ให้ เช่นการกำหนดแถว หลัก Ending ฯลฯ ดังรูปครับ
QtiPlot สามารถนำเข้าข้อมูลได้หลายรูปแบบ
ในการนำเข้าข้อมูลผู้ใช้สามารถกำหนดตัวเลือกการนำเข้าต่าง ๆ ได้
เมื่อนำเข้าข้อมูลแล้วข้อมูลจะอยู่ในรูปของตาราง (Table) ซึ่งเราเลือกได้อย่างอิสระว่าจะให้คอลัมน์ใดเป็นแกน x คอลัมน์ใดเป็นแกน y โดยการคลิ๊กขวาที่หัวของคอลัมน์ครับ
ผู้ใช้สามารถกำหนดได้ว่าคอลัมน์ใดจะเป็นแกนใด รวมทั้งกำหนดค่าอื่น ๆ เช่นฉลากและชื่อแกนได้ด้วย
เราใช้เมนู Plot ทำการพล๊อตกราฟได้ทันที รูปแบบของการพล๊อตก็รวมรูปแบบยอดนิยมเกือบทั้งหมด ทั้ง Line Scatter และ Pie แต่ทั้งนี้การจะพล๊อตกราฟได้นั้นจะต้องเลือกคอลัมน์ y ที่จะพล๊อตเสียก่อน ในการพล๊อตเราสามารถกำหนดองค์ประกอบของการพล๊อตได้ทุกอย่าง ตั้งแต่ชื่อของพล๊อต (Title) ฉลากข้อมูล (Legand) ชื่อแกนและช่วงแกน (Axis) ภาพข้างล่างนี้จะเป็นตัวอย่างการพล๊อตข้อมูลที่ผมเตรียมไว้ครับ
ซึ่งกราฟที่พล๊อตสามารถส่งออกเป็นไฟล์กราฟิกได้หลายรูปแบบโดยใช้เมนู File -> Export Graph ครับ

แต่ถ้า QtiPlot จะทำได้แค่นี้ ผมใช้ Octave เอง หรือไม่ก็ tikz ดีกว่า อย่างที่กล่าวไว้ข้างต้นครับ ผมต้องหาเครื่องมือเพื่อทำ Mesh Plot ของข้อมูลขนาดใหญ่มาก ซึ่งจะเล่าให้ฟังในหัวข้อถัดไป

การพล๊อดกราฟ 3 มิติด้วยข้อมูลจาก Octave
วิธีการก็คล้ายกันครับ ผมจะแสดงตัวอย่างข้อมูล บันทึกข้อมูลที่จะพล๊อตลงในไฟล์ข้อความ และนำเข้าไฟล์ข้อความเข้าไปใน Qtiplot แล้วก็พล๊อตข้อมูลเป็นกราฟ 3 มิติ

ลองดูตัวอย่างการเตรียมข้อมูลนะครับ
> % Prepare the test data
> x = 1:10;
> y = 1:10;
> [xx,yy] = meshgrid(x,y);
> Data = sin(xx.+yy)./sqrt((xx.^2)+(yy.^2));
> % Prepare data for QtiPlot
> save -ascii Data.txt Data
การนำข้อมุลเข้าสู่ QtiPlot จะทำเช่นเดียวกันกับข้อมูล 2 มิติครับ แต่ต้องแปลงตาราง (Table) ให้เป็นเมตริกซ์ (Matrix) เสียก่อนโดยใช้เมนู Table -> Convert to Matrix -> Direct เราจะได้หน้าต่างเมตริกซ์ของข้อมูลชุดนี้มา เมื่อเราอยู่ในหน้าต่างเมตริกซ์ เมนูบาร์จะเปลี่ยนเป็นเมนูของเมตริกซ์ เราจะพล๊อตกราฟได้ตอนนี้โดยเลือกเมนู 3D Plot -> 3D Wire Surface ก็จะได้กราฟ 3 มิติสำหรับแสดงผลเมตริกซ์ครับ แน่นอนว่าเราสามารถตั้งสเกลแกนต่าง ๆ ได้ ตั้งชื่อแกนและชื่อพล๊อตได้ ปรับสีได้
พล๊อตข้อมูล Data ในแบบ 3 มิติ
ก็ถือเป็นการแนะนำโปรแกรมสำหรับพล๊อต 3 มิติสำหรับข้อมูลจำนวนมากนะครับ ถ้าข้อมูลไม่มากใช้ Octave นั่นแหละสะดวกดี สำหรับผม ๆ ใช้ QtiPlot สำหรับการแสดงผลการวิเคราะห์สัญญาณเสียงแคนครับ ขนาดของข้อมูลคือ 427x601 จุดครับ ผมเอาพล๊อตของข้อมุลบางส่วนมาให้ดูด้วย
ผลการวิเคราะห์เสียงแคน เลือกมาหลอดเดียวนะครับไม่ใช่ทั้งเต้า