แสดงบทความที่มีป้ายกำกับ Octave แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ Octave แสดงบทความทั้งหมด

วันอังคารที่ 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 จุดครับ ผมเอาพล๊อตของข้อมุลบางส่วนมาให้ดูด้วย
ผลการวิเคราะห์เสียงแคน เลือกมาหลอดเดียวนะครับไม่ใช่ทั้งเต้า

วันศุกร์ที่ 27 พฤษภาคม พ.ศ. 2554

เครื่องมือช่วยพล๊อตกราฟ

ช่วงหลายปีที่ผ่านมาผมทดลองใช้โปรแกรมสำหรับวิเคราะห์และประมวลสัญญาณแทน Matlab สลับไปสลับมาระหว่าง Octave กับ Scilab จุดด้อยของ 2 โปรแกรมนี้สำหรับคนที่คุ้นเคยกับ Matlab ก็คือการพล๊อตกราฟ กล่าวคือมันไม่ค่อยสะดวกสำหรับคนที่ชินกับระบบพล๊อตของ Matlab

หลังจากสำรวจรายการแพคเกจของ wheezy เกี่ยวกับการพล๊อตแล้วก็พบแพคเกจชื่อ plotdrop ซึ่งมีรายละเอียดน่าสนใจดังนี้ (จากรายละเอียดของแพคเกจ)
PlotDrop is designed for quick simple visualisation of 2D data series.
It is intended to be used in tandem with an external filesystem browser
such as GNOME's nautilus or KDE's konqueror. Files containing data are added
by dragging them from the browser to the file list.
อันที่จริงมีแพคเกจที่เกี่ยวกับ Data Visualization อีกเยอะเลยครับ แต่ตัวนี้มีลูกเล่นน้อยที่สุดทำให้รู้สึกว่าเรียนรู้ได้ง่ายที่สุด ก็เลยเลือกมาลองก่อน เราสามารถติดตั้งได้ทันทีโดย
# sudo apt-get install plotdrop
หากเป็นเครื่องของผมซึ่งเป็น wheezy แพคเกจนี้จะไปอยู่ในเมนูรูปภาพ (Graphic) ครับ เมื่อเรียกโปรแกรมนี้จากเมนูเราจะเห็นหน้าต่างแบบนี้
สิ่งที่เราต้องทำก็คือเอาข้อมูลให้โปรแกรมนี้ไป ข้อมูลจะต้องเป็น
  1. แฟ้มข้อความ เข้ารหัสแบบใดก็น่าจะได้ แต่ที่ผมใช้อยู่และไม่มีปัญหาคือ UTF-8
  2. ข้อมูลแยกหลัก (Column) กล่าวคือ ข้อมูล ก. อยู่หลัก 1 ข้อมูล ข. อยู่หลัก 2 ... อย่างนี้เรื่อยไป
  3. จำนวนแถว (Row) น่าจะต้องเท่ากัน ผมยังไม่เคยลองว่าถ้าจำนวนแถวไม่เท่ากันจะเกิดอะไรขึ้น
เราเรียกการจัดข้อมูลแบบนี้ว่า Delimated File และใน Octave เรามีคำสั่งที่ใช้จัดเตรียมชุดข้อมูลเพื่อพล็อตแบบนี้โดยใช้คำสั่ง dlmwrite ครับ เช่นถ้าเราต้องการพล็อตแกน x เป็นความถี่ในเวคเตอร์ f ขนาด 100x1 และแกน y เป็นความหนาแน่นสเปคตรัมกำลัง (Power Spectrum Density) P ขนาด 100x1 เช่นกัน เราจะใช้คำสั่ง dlmwrite สร้างแฟ้มข้อมูลที่ใช้กับ plotdrop ได้ดังนี้
octave> dlmwrite('mydlmfile.dlm',[f P]," ");
นี้หมายความว่า เราส่งข้อมูล f และ P ไปในเมตริกซ์เดียวกัน ส่งเข้าไปในแฟ้มข้อความธรรมดาชื่อ mydlmfile.dlm โดยที่ระหว่างข้อมูล f และ P จะคั่นด้วย Space (" ") เช่นถ้า
octave> f = [0 10 20 30]';
octave> P = [12 15 10 5]';
หน้าตาของแฟ้มข้อมูล mydlmfile.dlm จะเป็น
0 12
10 15
20 10
30 50
เราสามารถลากแฟ้มนี้ไปวางในพื้นที่ว่างในรูปข้างบนได้เลย หรือจะเรียกใช้คำสั่ง Series => Add File ... ก็ได้ เมื่อเราส่งข้อมูลให้ plotdrop ได้แล้ว เราสามารถ
  • เติมหัวเรื่อง ฉลากแกน x และฉลากแกน y ได้ในแท็ป Caption (แท็ปที่ 1)
  • เปลี่ยนขอบเขตของ x และ y ได้ในแท็ป Limits (แท็ปที่ 2)
  • เปลี่ยนหน้าตาการแสดงผลเช่น เป็นลอการิธึมในแกน x เป็นลอการิธึมในแกน y มีกริด ไม่มีกริด ฯลฯ ได้ในแท็ป Appreance (แท็ปที่ 3)
  • เพิ่มคำสั่งอื่น ๆ ในในแท็ปที่ 4 ผมยังไม่รู้ว่ามีคำสั่งพิเศษอะไรที่ใช้ได้บ้าง ตอนนี้ยังไม่จำเป็นเลยไม่ได้สนใจ
เมื่อเราเตรียมข้อมูลใน plotdrop แล้ว เราสามารถพล็อตกราฟดูได้ทันที หากเราพอใจและต้องการจะนำกราฟไปใช้ในเอกสารอื่น ๆ สามารถเก็บพล็อตลงแฟ้มได้โดย Plot => Plot to File ... ซึ่งผู้ใช้สามารถเลือกรูปแบบของแฟ้มส่งออกได้หลากหลายเช่น EPS PS LaTeX SVG PNG และอื่น ๆ สำหรับผมถ้าจะเอามาใช้กับ LibreOffice ผมก็ใช้แฟ้ม PNG นี่แหละครับ ง่ายดี

ผมพบว่าโปรแกรม plotdrop ตัวนี้ใช้ง่ายดี ช่วยให้ผมพล็อตกราฟจาก Octave เพื่อไปใช้ต่อในงานเอกสารอื่น ๆ ได้ง่าย เราสามารถเติม Caption ต่าง ๆ ได้สะดวก พล็อตดูได้ก่อน ถ้าชอบค่อยจัดลงแฟ้ม อย่างไรก็ตาม จากการทดลองใช้พบว่าในส่วนของ Caption ต่าง ๆ ยังไม่รองรับภาษาไทยครับ หากกรอกภาษาไทยลงไป เวลาพล็อตผมจะเห็นเป็นตัวเหลื่ยม ๆ แบบนี้ [] ทุกตัวอักษรไป ถ้ารองรับภาษาไทยด้วยคงจะดี

หากใครใช้แล้วมีเทคนิคอะไรจะมาแบ่งกัน ก็อย่าลืมมาบอกกันนะครับ