MATLAB绘图高级指南

MATLAB绘图高级指南

1.序言

MATLAB图形对象是实现数据可视化(data visualization)的一种重要手段。在处理数据的过程中,必不可少的一个方法就是图形可视化。但是MATLAB基本的绘图功能有时候并不能满足数据可视化的需求,无论是从美观(python的Matplotlib、pyecharts)度还是信息明确度角度看。但这并不意味着MATLAB不能绘制出更好的图形。MATLAB绘图的定制程度很高,因此需要对MATLAB图像对象有更深入的理解。

2.图形对象层次结构

2.1 层级结构

图形对象是 MATLAB® 用来以图形的形式显示数据的可视化组件。每个对象都有一个名为 句柄(handle) 的唯一标识符。通过设置图形对象 属性(property) 来操作现有图形对象的特征。例如修改坐标轴数据的显示方式、线条颜色、线条宽度、自定义回调函数等。当我们调用plot函数时候, MATLAB 会自动执行一系列步骤生成图形。这些步骤包括创建对象和将这些对象属性值设置为适合特定图形的值。MATLAB的图像对象按照如下的方式进行组织:

图形对象的层次结构本身反映出对象之间的包含关系。matlab的图窗对象包括:Root(根节点)、Figure(图窗)、Annotation(标注)、Axes(坐标区)、Illustration(图例)、UI(用户界面控件)。例如,使用 plot 函数创建线图。坐标区对象为表示数据的线定义了参考系。图窗是显示图形的窗口。图窗包含坐标区,坐标区包含线条、文本、图例以及其他用于表示图形的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
try
close('figure')
catch
end

f1 = figure('name', 'figure', 'color', 'w', 'menubar', 'figure');
subplot(121)
x = linspace(-2 * pi, 2 * pi);
y1 = 6 .* sin(x);
y2 = 6 .* cos(x);
plot(x, y1, x, y2)
title('axes 1')
xlabel('axis-x-1')
ylabel('axis-y-1')
legend('1-1', '1-2')

subplot(122)
x = linspace(0, 3 * pi, 200);
y = cos(x) + rand(1, 200);
sz = 25;
c = linspace(1, 10, length(x));
scatter(x, y, sz, c, 'filled')
xlabel('axis-x-2')
ylabel('axis-y-2')
title('axes 2')

图中,红色框:figure,绿色框:axes,黄色框:Annotation(箭头),褐色框:illustration(legend)。

2.2 图像对象继承关系

对象间的关系保存在 ParentChildren 属性中。例如,坐标区的父级是一个图窗。坐标区的 Parent 属性包含了该坐标区所在图窗的句柄。

同样,图窗的 Children 属性包含了其所含的所有坐标区。图窗 Children 属性还包含其所含的其他所有对象,如图例和用户界面对象。

1
2
3
% 3*1 Group
graph_children = f1.Children()

1
2
3
4
5
3×1 graphics 数组:

Axes (axes 2)
Legend (1-1, 1-2)
Axes (axes 1)
1
2
% axes 1的父对象
graph_children(1).Parent
1
2
3
4
5
6
7
Figure (1: figure) - 属性:

Number: 1
Name: 'figure'
Color: [1 1 1]
Position: [680 558 560 420]
Units: 'pixels'

2.3 groot(修改图窗默认值)

groot使用图形根对象。使用 groot 访问根属性。绘图的默认属性都是由groot的设定的默认值决定,groot能修改根图形的属性root(Root 对象是图形对象树的根。Root 属性包含有关图形环境和图形系统的当前状态的信息。使用圆点表示法引用特定的对象和属性。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
% 获取根图像属性(root)
get(groot)

%{
CallbackObject: [0×0 GraphicsPlaceholder]
Children: [1×1 Figure]
CurrentFigure: [1×1 Figure]
FixedWidthFontName: 'SimHei'
HandleVisibility: 'on'
MonitorPositions: [1 1 1920 1080]
Parent: [0×0 GraphicsPlaceholder]
PointerLocation: [781 725]
ScreenDepth: 32
ScreenPixelsPerInch: 96
ScreenSize: [1 1 1920 1080]
ShowHiddenHandles: 'off'
Tag: ''
Type: 'root'
Units: 'pixels'
UserData: []
%}

使用groot还能为其他类型的对象设置根级别的默认值。例如每次绘图时对于线条,希望其线宽(LineWidth属性)默认为2。则可以通过groot实现。

1
set(groot,'defaultLineLineWidth',2);

指定属性值为 'remove' 会去除用户定义的默认值。

1
set(groot,'defaultSurfaceEdgeColor','remove')

指定属性值为 'factory' 将会让属性设置为其出厂定义值。例如,这些语句将曲面 hEdgeColor 设置为黑色(其出厂设定),无论定义的默认定义值为何值:

1
2
3
set(gcf,'defaultSurfaceEdgeColor','g')
h = surface(peaks);
set(h,'EdgeColor','factory')

3.保存图窗为其他格式的图片

3.1 saveas

将图窗保存为特定文件格式。

基本用法包括:

1
2
saveas(fig,filename)
saveas(fig,filename,formattype)

saveas(fig,filename)fig 指定的图窗或 Simulink® 模块图保存到 filename 文件中。将文件名指定为字符向量或字符串,包括文件扩展名,例如 'myplot.jpg'。文件扩展名用于定义文件格式。如果不指定扩展名,则 saveas 会将图窗保存为 FIG 文件。要保存当前图窗,请将 fig 指定为 gcf

saveas(fig,filename,formattype) 使用指定的文件格式 formattype 创建文件。如果不在文件名中指定文件扩展名(例如 'myplot'),则与指定的格式对应的标准扩展名会自动附加到文件名后面。如果指定了文件扩展名,该扩展名不必与文件格式相匹配。saveas 为该格式使用 formattype,但会将文件保存为指定的扩展名。因此,文件扩展名可能与使用的实际格式不匹配。

3.2 imwrite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function SaveFigure2Img(graph_object, imgfile, varargin)
% 功能:
% 将当前figure保存为image;
% 定义:
% SaveFigure2Img(imgfile,varargin)
% 输入:
% graph_object,图窗对象(figure|axes)
% imgfile,目标image全路径,e.g:D:/xx/A.png
% varargin,保留参数
% 输出:
% none

%%
% 捕获坐标区或图窗作为影片帧
cur_frame = getframe(graph_object);
% 返回与影片帧关联的图像数据
im = frame2im(cur_frame);
% 将图像写入图形文件
imwrite(im, imgfile);
end

3.3 生成GIF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
clc;
clf;
%白色背景
% axis([-2, 2, -2, 2]);
xlabel('X轴');
ylabel('Y轴');
%四周的边框
box on;
%绘图区域
t = 0:0.02:10;
Nt = size(t, 2);
x = 2 * cos(t(1:Nt));
y = sin(t(1:Nt));
%循环绘图
for i = 1:Nt
cla;
hold on;
plot(x, y)
plot(x(i), y(i), 'o');
frame = getframe(gcf);
imind = frame2im(frame);
[imind, cm] = rgb2ind(imind, 256);

if i == 1
imwrite(imind, cm, 'test.gif', 'gif', 'Loopcount', inf, 'DelayTime', 1e-4);
else
imwrite(imind, cm, 'test.gif', 'gif', 'WriteMode', 'append', 'DelayTime', 1e-4);
end

end

4.绘制动图

4.1 animatedline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
%%
% clf用来清除图形的命令。一般在画图之前用。
clf;
clc;
axis([-2, 2, -2, 2]);
% axis square 当前坐标系图形设置为方形,刻度范围不一定一样,但是一定是方形的。
% axis equal 将横轴纵轴的定标系数设成相同值,即单位长度相同,刻度是等长的,但不一定是方形的。
axis equal;
grid on;

h = animatedline('Marker', 'o', 'color', 'b', 'LineStyle', 'none');
t = 6 * pi * (0:0.02:1);

for n = 1:length(t)
addpoints(h, 2 * cos(t(1:n)), sin(t(1:n)));

% 一般是为了动态观察变化过程 pause(a)暂停a秒后执行下一条指令
pause(0.5);

% 可以用drawnow update加快动画速度
drawnow update;
end

4.2 movie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
%%
clc; clear;

% 初始化一个电影矩阵
M = moviein(16);
% 创建电影
for k = 1:16
plot(fft(eye(k + 16)));
axis equal;
% 调用getframe函数生成每个帧
M(k) = getframe;
end

% 调用movie函数将电影动画矩阵M(k)播放5次
movie(M, 5);

% 将前面创建的电影动画中添加一个垂直的滚动条
h = uicontrol('style', 'slider', 'position', [10 50 20 100], 'Min', 1, 'Max', 16, 'Value', 1);

for k = 1:16
plot(fft(eye(k + 16)));
axis equal;
set(h, 'Value', k);
% gcf为返回当前图形窗口句柄
M(k) = getframe(gcf);
end

clf;
axes('Position', [0 0 1 1]);
movie(M, 5);

5.图窗按键回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
%% matlab figure keypressdown callback use
clc;
tcf();
figure('name', 'deserado', 'color', 'w', 'KeyPressFcn', @isEscPressDown);
text(0, 0, 'desperado,why don''t you come to your senses,come down your fences');
axis([-1, 40, -1, 1])

for k = 1:1:100
pause(0.1);
if strcmpi(get(gcf, 'CurrentCharacter'),char(27))
disp('esc pressdown');
break;
end
end
disp('function break down');

%% callback function
function isEscPressDown(src, event)
fprintf('%s\n', get(gcf, 'CurrentCharacter'));
end

6.数据游标模式

启用数据游标模式。数据提示是显示关于单个数据点的信息的小文本框。在 R2018b 之前的版本中,使用 datacursormode 函数创建和编辑数据提示。通过使用 datacursormode 创建数据游标管理器对象来控制数据提示的外观和行为。

从 R2018b 开始,您可以改用内置交互来创建和编辑数据提示。内置交互不要求您启用某种模式,并且比交互模式响应更快。

test.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
% 修改数据游标格式
clc;
nbt_lat_lon_h = [104.058567643123, 30.547872167734, 467.946972989477
104.058567183453, 30.548014837274, 468.115972990170
104.058730768827, 30.548018797743, 467.900972989388
104.058889206422, 30.547874726343, 468.024972987361
104.058895271369, 30.548019508539, 469.051972987130
104.058728300713, 30.547880364315, 469.601972988807];

[x_1, y_1, ~] = latlon_to_xy(30.547872167734, 104.058567643123);
[x_2, y_2, ~] = latlon_to_xy(30.548019508539, 104.058895271369);
% lat:30.5478721677,lon:104.0585676431
x_s = linspace(x_1, x_2, 200);
y_s = linspace(y_1, y_2, 200);
[x_s, y_s] = meshgrid(x_s, y_s);

tcf('map-grid');
f1 = figure('name', 'map-grid');
hold on
dcm_obj = datacursormode(f1);
% 添加数据游标变化回调函数,在对话窗中打印当前游标数据
set(dcm_obj, 'UpdateFcn', @modify_cursor_callback)
mesh(x_s, y_s, zeros(200, 200))
plot(x_s(1), y_s(1), 'r*')
text(x_s(1), y_s(1), '1')
plot(x_s(end), y_s(end), 'b*')
text(x_s(end), y_s(end), '5')
view(0, 90)
grid minor

modify_cursor_callback.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function output_txt = modify_cursor_callback(obj, event_obj)
% Display the position of the data cursor
% obj Currently not used (empty)
% event_obj Handle to event object
% output_txt Data cursor text string (string or cell array of strings).

pos = get(event_obj, 'Position');
x_text = sprintf('%.10f', pos(1));
y_text = sprintf('%.10f', pos(2));
output_txt = {['X: ', x_text], ...
% 此处的pos(1)后的数字,即X轴的数据游标的显示精度位数
['Y: ', y_text]};
% 此处的pos(2)后的数字,即Y轴的数据游标的显示精度位数

% If there is a Z-coordinate in the position, display it as well
if length(pos) > 2
z_text = sprintf('%.10f', pos(3));
output_txt{end + 1} = ['Z: ', z_text];
% 此处的pos(3)后的数字,即Z轴的数据游标的显示精度位数
fprintf('x:%s,y:%s,hei:%s\n', x_text, y_text, z_text);
end

% [x,y]转换为[lat,lon]
if true
[lat, lon] = xy_to_latlon(pos(1), pos(2), 1.832595714594046);
fprintf('lat:%0.10f,lon:%0.10f\n', lat, lon);
end

end

Reference

1.Graphics Object Hierarchy - MATLAB & Simulink - MathWorks China

2.图形根对象 - MATLAB groot - MathWorks 中国

3.图形环境和状态信息 - MATLAB - MathWorks 中国

4.默认属性值 - MATLAB & Simulink - MathWorks 中国

5.将图窗保存为特定文件格式 - MATLAB saveas - MathWorks 中国

6.启用数据游标模式 - MATLAB - MathWorks 中国

7.Pursuit Curves » Steve on Image Processing with MATLAB - MATLAB & Simulink (mathworks.com)

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2023 Wh
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信