1. การพอร์ตกราฟขั้นสูง

ในหลักสูตรพื้นฐาน 1 เราได้เรียนรู้วิธีการพอร์ตกราฟ อย่างง่ายกันมาแล้วนะครับ คราวนี้เราจะมาเจาะลึกเรื่องการ plot กราฟ กันเลย

การปรับแต่งกราฟ

ถึงแม้ว่าเราจะสามารถปรับแต่งกราฟ หลังจากพอร์ตไปแล้วได้ (โดยปรับแต่งผ่านหน้า gui ของ MATLAB) แต่หากเราต้องรันโปรแกรมนั้นหลายๆ ครั้ง มันก็ไม่สะดวกที่เราจะต้องไปปรับแต่งเองทุกครั้ง ดังนั้นหากเราเขียนโปรแกรมกำหนดรูปแบบการแสดงผลลงไปเลย มันก็จะสะดวกมากกว่า และการพอร์ตกราฟทุกครั้งก็จะได้กราฟที่มีลักษณะเหมือนกันเป๊ะ

การปรับแต่งกราฟนั้น จะทำโดยกำหนดค่าผ่าน property ของกราฟ ซึ่งจะไม่ลงรายละเอียดว่า property ของกราฟมีอะไรบ้าง เพราะมันเยอะมาก แต่ทั้งหมดนี้มีเขียนอยู่ใน Help ของ MATLAB ดังนั้นเราจึงสามารถเปิดดูได้ตลอดเวลา หรืออีกวิธีคือ การใช้คำสั่ง get() เพื่อดูค่า property ตัวอย่างเช่น


ที่เราเห็นทั้งหมดนั้นรูปนั้น เป็นแค่ property บางส่วนของ figure ซึ่งใช้แสดงภาพ หรือ plot กราฟ เท่านั้น และไม่มีคำอธิบายใดๆ เลย ถ้าเราอยากรู้ประโยชน์ของ property ตัวไหน ผมแนะนำว่าให้เอาชื่อของมันไปค้นหาใน google จะได้คำตอบเร็วที่สุดนะครับ แต่อย่างไรก็ตามชื่อของ property ทั้งหมด จะค่อนข้างเดาได้ง่าย รวมทั้งหากเราใช้คำสั่ง get() เราก็จะเห็นค่าปัจจุบันของ property ตัวนั้นด้วย เช่น property ที่ชื่อว่า “Color” ใช้เก็บค่าในรูปแบบอาเรย์แบบ 1 แถว 3 คอลัมภ์ (อาเรย์ 1 มิติ) ซึ่งทำให้เรารู้ว่าหากเราจะกำหนดค่าให้ property ตัวนี้ เราต้องกำหนดในรูปแบบอาเรย์ที่มีขนาด 1 แถว 3 คอลัมภ์


เอาละครับ เมื่อเรารู้วิธีการหาชื่อ property ของกราฟแล้ว ต่อไปคือวิธีการกำหนดค่าให้ property นั้นๆ ซึ่งทำได้ 2 วิธีคือ

1. กำหนดค่าให้โดยตรงเหมือนตัวแปรทั่วไป เช่น
>> f.Color = [1  1  1];

2. ใช้คำสั่ง set() ตัวอย่างเช่น
>> set(f, ‘Color’, [0.5  0.5  0.5]);

ซึ่งทั้ง 2 วิธีนี้จะให้ผลลัพธ์เหมือนกัน แต่โดยส่วนตัวผมชอบใช้คำสั่ง set() มากกว่า เพราะการกำหนดค่าแบบที่ 1 นั้น มันดูคล้ายกับการกำหนดค่าให้กับตัวแปรประเภท struct (ซึ่งจะได้เรียนในหัวข้อที่ 3) ดังนั้นเพื่อให้ง่ายต่อการแยกแยะประเภทข้อมูล ผมจึงใช้ set เพื่อกำหนดค่าให้กับ object เท่านั้น และใช้ = เพื่อกำหนดค่าให้ตัวแปร

เอาละครับเมื่อทราบวิธีการกำหนดค่าให้ property แล้ว เราก็มาดูตัวอย่างกันได้เลย

1. จง plot กราฟ sine wave และกำหนดค่าการแสดงผลให้สวยงาม
*หมายเหตุ ในบรรทัดแรกของโปรแกรมจะมีคำสั่ง close all เพิ่มเข้ามา ซึ่งคำสั่งนี้ทำหน้าที่ปิด figure ทั้งหมดที่เปิดอยู่

clc;clear;close all;

t = 0.01:0.01:3*pi;
y = sin(t);
plot(t,y,'-r','linewidth',3);   % more info please see in HELP
set(gca,'fontsize',14);
set(gca,'fontweight','bold');
set(gca,'fontname','tahoma');
xlabel('Time (\mus)','fontsize',14,'fontweight','b')
ylabel('Amplitude','fontsize',14,'fontweight','b')
title('Sine wave (Grid OFF)','fontsize',16,'fontweight','b')
grid off;

ผลรัน
(ในบรรทัดสุดท้ายของโค้ด เปลี่ยนจาก grid off เป็น grid on)

(พอร์ตแบบ grid off)

ในบรรทัดที่ 5 เราจะเห็นว่าคำสั่ง plot นั้นมี input เพิ่มขึ้น จากที่เราเคยเรียนในหลักสูตรพื้นฐาน 1 ซึ่ง input ที่เพิ่มขึ้นมาในตัวอย่างนี้มี 2 ตัวคือ

‘-r’ หมายความว่า ให้พอร์ตเป็นเส้นทึบสีแดง ถ้าหากใครสนใจสามารถดูสัญลักษณ์ของเส้น และตัวย่อของสีได้ใน Help

‘linewidth’ คือ คำสั่งที่ใช้กำหนดความกว้างของเส้นกราฟ ซึ่งในตัวอย่างนี้กำหนดให้เท่ากับ 3

ส่วนคำสั่ง set() ทั้ง 3 คำสั่งด้านล่าง คือการกำหนดค่าให้ Axes (ซึ่งเป็นชื่อเรียก object ที่เอาไว้ใช้แสดงภาพ หรือพอร์ตกราฟ) โดยเราใช้คำสั่ง gca (ย่อมาจาก “get current axes”) เพื่อกำหนดค่าไปที่ property ของ axes ปัจจุบัน ซึ่ง axes ปัจจุบัน คือ axes ที่ถูกสร้างขึ้นมาล่าสุด ดังนั้นเราจึงนิยมใช้คำสั่ง set() ทันทีหลังจากใช้คำสั่ง plot เพราะหากในโปรแกรมของเรามีการ plot กราฟ หลายกราฟ หากเราใช้คำสั่ง set หลังจาก plot ทุกกราฟเสร็จแล้ว คำสั่งดังกล่าว จะมีผลกับกราฟสุดที่ที่เรา plot เท่านั้น

ส่วนด้านหลัง gca คือชื่อ property และค่าที่กำหนดให้กับ property นั้นๆ

คำสั่ง xlabel คือ คำสั่งกำหนดชื่อให้กับแกน x

คำสั่ง ylabel คือ คำสั่งกำหนดชื่อให้กับแกน y

คำสั่ง title คือ คำสั่งกำหนดชื่อให้กราฟ

ซึ่งผู้อ่าจะสังเกตุเห็นว่าในบรรทัดที่ 9 ในวงเล็บเขียนเอาไว้ว่า (\mus) แต่เมื่อแสดงผลออกมา เรากลับเห็นว่าข้อความส่วนนี้กลายเป็นตัวอักษร “มิว” ของกรีกแทน ซึ่งการเขียนแบบนี้ เป็นการเขียนแบบพิเศษ เพื่อใช้เรียกชื่ออักษรกรีก และนอกจาก \mu แล้วยังมีตัวอักษรพิเศษอื่นๆ อีกมากมาย ดังนี้

คำสั่งปรับเปลี่ยนรูปแบบการแสดงผล

Modifier
Description
Example
^{ }
ตัวยกกำลัง
'text^{superscript}'
_{ }
ตัวห้อย
'text_{subscript}'
\bf
ตัวหนา
'\bf text'
\it
ตัวเอียง
'\it text'
\sl
ตัวเอียง (ใช้เหมือนกันกับ \it)
'\sl text'
\rm
ตัวอักษรปกติ
'\rm text'
\fontname{specifier}
กำหนดประเภทตัวอักษร
'\fontname{Courier} text'
\fontsize{specifier}
กำหนดขนาดตัวอักษร
'\fontsize{15} text'
\color{specifier}
กำหนดสีตัวอักษร เช่น red, green, yellow,
magenta, blue, black, white, gray,
darkGreen, orange, หรือ lightBlue.
'\color{magenta} text'
\color[rgb]{specifier}
กำหนดสีตัวอักษรในรูปแบบ RGB
'\color[rgb]{0,0.5,0.5} text'

คำสั่งแสดงผลอักษรกรีก

Character Sequence
Symbol
Character Sequence
Symbol
Character Sequence
Symbol
\alpha
α
\upsilon
υ
\sim
~
\angle
\phi
Φ
\leq
\ast
*
\chi
χ
\infty
\beta
β
\psi
ψ
\clubsuit
\gamma
γ
\omega
ω
\diamondsuit
\delta
δ
\Gamma
Γ
\heartsuit
\epsilon
ϵ
\Delta
Δ
\spadesuit
\zeta
ζ
\Theta
Θ
\leftrightarrow
\eta
η
\Lambda
Λ
\leftarrow
\theta
θ
\Xi
Ξ
\Leftarrow
\vartheta
ϑ
\Pi
Π
\uparrow
\iota
ι
\Sigma
Σ
\rightarrow
\kappa
κ
\Upsilon
ϒ
\Rightarrow
\lambda
λ
\Phi
Φ
\downarrow
\mu
µ
\Psi
Ψ
\circ
º
\nu
ν
\Omega
Ω
\pm
±
\xi
ξ
\forall
\geq
\pi
π
\exists
\propto
\rho
ρ
\ni
\partial
\sigma
σ
\cong
\bullet
\varsigma
ς
\approx
\div
÷
\tau
τ
\Re
\neq
\equiv
\oplus
\aleph
\Im
\cup
\wp
\otimes
\subseteq
\oslash
\cap
\in
\supseteq
\supset
\lceil
\subset
\int
\cdot
·
\o
ο
\rfloor
\neg
¬
\nabla
\lfloor
\times
x
\ldots
...
\perp
\surd
\prime
´
\wedge
\varpi
ϖ
\0
\rceil
\rangle
\mid
|
\vee
\langle
\copyright
©

นอกจากนี้เรายังสามารถใช้คำสั่ง text() เพื่อแสดงข้อความบนกราฟได้ด้วย ตัวอย่างเช่น

clc;clear;close all;

t = 0.01:0.01:3*pi;
g = plot(0,0,'-b','linewidth',1);
s = text(0,0,num2str(0),'fontsize',12);

set(gca,'fontsize',14);
set(gca,'fontweight','bold');
set(gca,'fontname','tahoma');
xlabel('Time (\mus)','fontsize',14,'fontweight','b')
ylabel('Amplitude','fontsize',14,'fontweight','b')
title('Sine wave (Grid OFF)','fontsize',16,'fontweight','b')
grid off;
xlim([0 10])
ylim([-1 1])

for m=1:length(t)
    x = t(m);
    y = sin(x);
    ax = get(g,'Xdata');
    ay = get(g,'Ydata');
    Nx = [ax x];
    Ny = [ay y];
    set(g,'Xdata',Nx);
    set(g,'Ydata',Ny);
    set(s,'Position',[x y 0]);
    set(s,'String',num2str(y));
    pause(0.02);
end

ผลรัน



หากผู้อ่านลองรันโค้ดโปรแกรมตามตัวอย่างข้างต้น คุณจะเห็นว่า “กราฟมันเคลื่อนไหว” หรือพูดอีกอย่างก็คือ “Animation” นั่นเอง ซึ่งคำสั่ง text ใช้แสดงค่าของกราฟ ณ เวลาปัจจุบัน และเปลี่ยนตำแหน่งไปเรื่อยๆ ตามกราฟ

คำสั่ง xlim และ ylim คือคำสั่งที่ใช้กำหนดของเขตการแสดงผลของแกน x และแกน y ส่วนคำสั่ง pause() ใช้หยุดการทำงานของโปรแกรม ในหน่วยวินาที และตัวเลขที่น้อยที่สุดที่ใส่ได้คือ 0.01 วินาที ส่วนเหตุผลที่เราต้องใช้คำสั่ง pause เพื่อหยุดการทำงานของโปรแกรมนั้นก็เพราะว่า เราต้องให้เวลา “จอภาพ” แสดงผลการเปลี่ยนแปลงของกราฟ เพราะถ้าเราให้โปรแกรมทำงานอย่างต่อเนื่อง คอมพิวเตอร์ก็จะไม่มีเวลามาประมวลผลการแสดงภาพ ทำให้เราไม่เห็นภาพเคลื่อนไหว ซึ่งในจุดนี้หลายๆ คนเข้าใจผิด และใช้คำสั่ง draw now เพื่อบังคับให้โปรแกรมแสดงผล ซึ่งเป็นการแก้ที่ปลายเหตุ และต่อให้แสดงผลได้ การแสดงผลก็จะช้า และดูไม่ต่อเนื่อง เพราะแก้ปัญหาไม่ถูกจุด

ส่วนบรรทัดที่ 22 และ 23 นั้น คือการรวมอาเรย์แบบต่อด้านข้าง ซึ่งได้อธิบายไปแล้วในหลักสูตรพื้นฐาน 1

จุดเด่นของโปรแกรมนี้คือ เราใช้การปรับเปลี่ยนค่าไปที่ property ของกราฟโดยตรง ทำให้การแสดงผลรวดเร็วขึ้น และลักษณะต่างๆ ของกราฟ เช่น สี เส้น ขนาดตัวอักษร จะยังคงเหมือนเดิมตลอด เพราะเราไม่ได้เปลี่ยนค่า property เหล่านี้ในระหว่างการ วนลูปแสดงผล ในลูปการแสดงผล ค่าที่เปลี่ยนไปมีแค่ Xdata  Ydata ของกราฟ และ ตำแหน่ง กับ ข้อความของ text เท่านั้น

ถ้าหากเราใช้คำสั่ง plot ในลูป นั่นหมายความว่าโปรแกรมจะทำการ “ลบ” และ “สร้างใหม่” ทุกครั้งที่วนลูป ทำให้คุณลักษณะต่างๆ ของกราฟที่เรากำหนดไว้หายไป และโปรแกรมก็จะแสดงผลได้ช้าลง เพราะต้องคอยลบ และสร้างใหม่ตลอดเวลา แต่ถ้าเราใช้คำสั่ง hold on เพื่อคงการแสดงผลของกราฟอันเดิมเอาไว้ มันก็จะกลายเป็นการ plot กราฟใหม่บนกราฟเดิม ซึ่งหมายความว่า หากเราวนลูป 1000 รอบ บนกราฟที่เรามองเห็นก็จะเป็นกราฟ 1000 เส้นที่ซ้อนทับกันอยู่ ทำให้โปรแกรมเปลือง memory ในการเก็บข้อมูล


จบหัวข้อที่ 1

ความเห็น

โพสต์ยอดนิยมจากบล็อกนี้

การแก้สมการ Differential ด้วย MATLAB

การหาค่าเฉลี่ยโดยไม่ต้องเก็บค่า

ว่าด้วยเรื่องของ ERROR