MATLAB App Designer —— 手撕代码学习总结
MATLAB App Designer 是 MATLAB 提供的一个图形化界面工具,用于创建交互式应用程序。
文章目录
- 一、简介
- 二、函数与实战
- 神奇BUG在副本卡BOSS
一、简介
MATLAB App Designer
是 MATLAB 提供的一个图形化界面工具,用于创建交互式应用程序。通过 App Designer,用户可以拖放组件,编写脚本,并集成图形界面与后台逻辑,创建可视化和用户交互的应用程序。App Designer 提供了比传统的 GUI 开发工具(如 guide)更强大的功能和更现代的界面设计。
MATLAB Online(在线版MATLAB)
官网地址:https://matlab.mathworks.com/
备注:需要注册后登录账号(使用方式与离线版等同)
MATLAB App Designer 官方文档
MATLAB App Building 包含 GUIDE 和 App Designer 文档。
MATLAB App Designer 官方示例
二、函数与实战
(一)
(1.1)csvread() 函数
11、只能读取纯数值的csv文件;
22、当csv文件中有字符串等其他类型的值时,将跳过该行或该列;
33、csv文件中的空项,读到矩阵中时,会初始化为0;
(1)M = csvread('filename'); % 直接输入文件名,将数据读到矩阵M中。
(2)M = csvread('filename', row, col); % 指定开始读取位置的(row)和(col);当 row = 0,col = 0 时表示从文件中第一个数开始读。
(3)M = csvread('filename', row, col, range); % 选定读取范围。range= [R1 C1 R2 C2],(RI,C1)是读取区域的左上角,(R2,C2)是读取区域的右下角。另外,要求row = R1. co1 = C1。
- 备注:(.xlsx) 的读取与存储丰常耗时,(.csv)就很人性化。
- 纯文本csv、txt无法保存修改后的格式,关闭后系统将自动恢复。可以尝试另存为并选择 xlsx 格式保存。
- 纯文本csv无法保存第二个sheet(sheet2),关闭后系统将自动删除。
(1.2)xlsread() 函数
11、读取并处理 Excel 中的数字、字符(中英文);—— 也可以读取csv文件
22、对(部分)非数值单元,将处理为 nan;
33、对前几行(列)皆为非数值,将直接忽略;
(1)[data, str] = xlsread('filename.xlsx'); % 数据都在data中,字符都在str中;
(2)num = xlsread('filename'); % 默认读取 sheet1 中的数据;
(3)num = xlsread('filename', sheet); % 读取 excel 文件中的指定 sheet;
(4)num = xlsread('filename', sheet, 'range'); % 指定读取范围。例如:'D2:H4'表示以 D2 和 H4 为对角定点的矩形域;
(1.3)readtable() 函数
(1)T = readtable(filename)
% 通过从文件中读取列向数据来创建表。
[filename, pathname] = uigetfile({'*.*'}, 'File Selector'); % 打开文件。(获得文件路径和文件名)
if isequal(filename, 0) || isequal(pathname, 0)
return
end
File_Path = [filename, pathname]; % 字符串拼接(文件路径+文件名)
app.address.Text = File_Path; % 将文件路径保存到文本框中
[file_data] = readtable(filename) % 读取数据
app.UITable.Data = file_data; % 数据显示在UITable中
app.UITable.ColumnName = file_data.Properties.VariableNames; % 复制xlsx内容中的表头到UITable中(通过变量ColumnName存储)
(2)T = readtable(filename,opts)
% 使用导入选项 opts 创建表。
opts = detectImportOptions(filename); % 创建导入选项,定制多个变量的数据类型,然后读取数据。
opts.MissingRule = 'omitrow'; % 忽略发生错误的行
[T] = readtable(filename, opts);
(3)T = readtable(___,Name,Value)
% 基于文件创建一个表,并通过一个或多个名称-值对组参数指定其他选项。
例如:可以指定 readtable 是将文件的第一行读取为变量名称还是数据。
(1.4)writetable() 函数
将表写入到电子表格(.xls)中特定的工作表和范围,(.csv)不行
11、只支持读取(.csv)的第一个sheet;
22、支持读取(.xls)的指定sheet;
33、file_data读取的数据必须为数值、元胞或逻辑数组;
44、file_path需要具体到文件的扩展名;例如:'test.csv'
、'test.xlsx'
;
(1)writetable(file_path, file data); % 表头默认自动添加(表头不存在,系统将自动添加Var1... Var15)
(2)writetable(file_path, file_data, 'WriteVariableNames', false); % 表头可以设置隐藏(true/false)
(3)writetable(T, 'myData.xls', 'Sheet', 1, 'Range' , 'B2:F6'); % 将表写入到电子表格(.xls)中特定的工作表和范围,(.csv)不行
(1.5)获取 table 类型数据的表头(表头:存在或不存在)
if table_data.Properties.VariableNames(4) = "PATIENTID"
PATIENTID_Var = table_data.PATIENTID(jj); % 若表头PATIENTID存在,则直接提取
else
PATIENTID_Var = table_data.Var4(jj); % 若表头PATIENTID消失,则提取系统自动填充的表头
end
【说明】 table(表)数据在移植过程中,若表头不存在或(自动)消失,系统将自动填充:Var1 - VarN
【访问表头】file_data.Properties.VariableNames(jj);
表示访问(table类型的file.data文件,属性(Properties)列表中的变量名(VariableNames:即所有表头名称),第 jj 列表头
【访问数据】file_data.TYPE(jj)
:表示访问(table类型的file_data文件)中,表头TYPE (列),对应的第 ( jj ) 行数据
(1.6)table() 添加表头(添加行名)
(1) T = table(var1, var2, ..., varN);
% 根据输入变量创建表。不同变量的列数和数据类型可以不同(如:cell/mat等),但所有变量的行数必须相同。
(2) T = table(A, B, 'VariableNames', {'Card', 'ID'}, 'RowNames', {'Mean':'SD'});
% 添加表头与行名。若只添加表头不添加行名:table(A, B, 'VariableNames', {'Card', 'ID'});
(3) T = array2table( 矩阵A, 'VariableNames', {'矩阵有几列,表头就有几个"});
% 该方法适用于表头需要分别命名的情况。如:Card、ID、K、Calib。
(4) T = array2table( Alg );
% 该方法适用于表头太多的情况。系统自动命名:Alg1、Alg2...AlgN;
(1.7)组件赋值
app.label.Text = File_Path; % 将文件路径保存到label文本框中
app.UITable.Data = file_data; % 将数据显示在UITable中
app.Value.Edit_Field.Value = value; % 将value显示在Edit Field中
(1.8)回调、函数、属性
代码浏览器
包含三个部分:回调、函数、属性,可以按需求添加。其中,函数和属性
分私有和公共两种方式。
- 私有/公共函数可以有多个参数,但是第一个参数必须是
app
,如果在函数中没有使用到app
这个参数,则可以使用~
来代替。 - 调用函数时,无论是否使用到
~
,app
都必须作为输入参数。
function magnify(~, f1) % 函数定义
c = 1+1;
end
temp_string = magnify(app, f1) % 函数调用
(二)
(2.1)缺失数据 NaN 与 missing
% 不同数据类型,表示缺失值不同。
(1) 数值数据类型(double):使用 NaN (非数字)表示缺失值。
(2) 数据类型(datetime、string和categorical); 使用 missing 值表示缺失数值数据或其他类型的数据。MATLAB自动将 missing 值转换为数据的原生类型。
(2.2)NaT 非时间(Not-a-Time)
(1) NaT; % 数据类型:datetime - 非时间(NaT:Not - a -Time)
(2) NaT(3); % 创建一个由 NaT 值组成的 3x3 datetime 矩阵。
(3) tf = isnat(A); % 返回大小与 A 相同且包含逻辑值 1(true) 和逻辑值 0 (false) 的日期时间数组;
(4) t = datetime; % 返回一个对应于当前日期和时间的标量 datetime 数组。
(2.3)解决数组中 NaN 的相关计算函数
A = [NaN, 2, 2, 2, 2];
(1) X = NaN(size(A)); % 创建一个由 NaN 值组成的、大小与现有数组相同的数组。
(2) mean = nanmean(A); % 删除 NaN 所在行,并且数据更新为:[2, 2, 2, 2],然后计算均值(原序列数据不改变)
(3) std = nanstd(A); % 删除 NaN 所在行,并且数据更新为:[2, 2, 2, 2],然后计算标准差(原序列数据不改变)
(4) R = corrcoef(D, 'Rows', 'complete'); % 删除 NaN 所在行,计算更新后矩阵 D 的 Pearson 相关系数,R 为对称矩阵 (原矩阵数据不改变)
% [备注1]R = corrcoef(A, B) % 计算序列 A 与序列 B 的 Pearson 相关系数;
% [备注2]R = (ρ(A, A) ρ(B, A); R = (ρ(A, A) ρ(B, A) ρ(C, A);
ρ(A, B) ρ(B, B)); ρ(A, B) ρ(B, B) ρ(C, B);
ρ(A, C) ρ(B, C) ρ(C, C));
(2.4)判断数据类型:空类型、NaN、基本数据类型
(1)isempty(A) % 判断数组是否为空:[ ] (空类型即 double类型);变量(值)只要初始化,则必定不为空
(2)~isnan(A) % 判断变量(值)是否不为 NaN
(3)isa(pi, 'double'); % 确定变量是否具有指定的数据类型(classname:double/single/char/str ing/cell/struct/table etc.)
(三)
(3.1)datestr 获取系统时间(now)
A = datestr(now, 31);
11、datestr - 生成指定格式的日期和时间,结果是字符类型;
22、now - 当前系统的日期和时间;
33、输出格式共有31种(用户可指定),以下是第31种格式:'yyyy-mm-dd HH:MM:SS'
def_format = 'mm-dd-HH-MM'; % 自定义格式
t_str = datestr(now, def_format);
(3.2)uigetfile / uigetdir / dir / isdir / mkdir / rmdir / isfolder / isfile
(00)[filename, pathname] = uigetfile({'*.m';'*.xlsx';'*.csv';'*.*'}, 'File Selector'); % 打开文件选择对话框。指定筛选器列表(4种)
(00)[filename, pathname] = uigetfile({'*.*'}, 'File Selector'); % 打开文件选择对话框。指定筛选器列表(所有文件)
(00)filepath = uigetdir; % 打开文件夹选择对话框;
(1)mkdir(folder_name); % 在当前文件夹下创建名为 folder name 的文件夹;
(2)rmdir(folder_name, 's'); % 删除文件夹(及其所有子文件夹和文件),其名称为folderName;
(3)All_File = dir(folderpath); % 列出当前文件夹/路径下的所有文件和文件夹;
(4)All_File(i).isdir; % 判断当前路径下输入(文件/文件夹)是否为文件夹(需跟随函数dir()使用);
(5)FileNames = All_File.name; % 提取所有(文件/文件夹)的文件名,转换为 n 行 1 列;
(6)isfolder('folderName'); % 判断当前路径下输入的(文件/文件夹)是否为文件夹;
(7)isfile('fileName'); % 判断当前路径下输入的(文件/文件夹)是否为文件(文件需包含后缀名);
(3.2.1)实战:uigetfile
[filename, pathname] = uigetfile({'*.*'}, 'File Selector');
if isequal(filename, 0) || isequal(pathname, 0) % 判断是否尚未选择文件就提前取消
return;
end
File_Path = [pathname, filename]; % 字符串拼接
app.Label.Text = File_Path; % 将文件路径保存到文本框中
% [file_data] = readtable(File_Path); % 读取数据
% app.UITable.Data = file_data; % 将数据显示在UITable中
% app.UITable.ColumnName = file_data.Properties.VariableNames; % 复制xlsx的表头到UITable中
(3.2.2)实战:uigetdir
11、将加载路径的所有文件通过app.Tree显示
- 组件库:按钮、标签、树、表(四个组件各一个,拖到画布中)
function ButtonPushed(app, event)
pathname = uigetdir; % 读取文件
if isequal(pathname, 0) % 判断是否尚未选择文件夹就提前取消
errordlg('没有选择文件,请重新选择!', '错误');
else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 记录当前目录下所有【文件夹+文件】
All_files = dir(pathname); % 获取当前路径下所有文件和文件夹
All_files_len = length(All_files);
folders = {0}; % 初始化文件夹
files = {0}; % 初始化文件
folder_num = 0; % 文件夹数量
file_num = 0; % 文件数量
for ii = 1:All_files_len
if ~(strcmp(All_files(ii).name, '.') || strcmp(All_files(ii).name, '..')) % 排除.和..
if All_files(ii).isdir % 判断是否为文件夹
folder_num = folder_num + 1;
folders{folder_num} = All_files(ii).name; % 保存所有文件夹
else
file_num = file_num + 1;
files{file_num} = All_files(ii).name; % 保存所有文件
end
end
end
VecFolders = folders';
VecFiles = files';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 将加载路径的所有文件通过app.Tree显示(无需拖拽组件,自定义代码构建)
delete(app.Tree) % 删除组件Tree
app.Tree = uitree(app.UIFigure);
app.Tree.SelectionChangedFcn = createCallbackFcn(app, @TreeSelectionChanged, true);
app.Tree.Position = [21 63 259 352]; % 自定义Tree的大小和位置
% 四个参数,其值都是从小到大:(1)调整左右(2)调整下上(3)矩阵大小-横向调整(4)矩阵大小-纵向调整
% 显示当前目录下所有【文件】
[FileNames_len, ~] = size(VecFiles);
for jj = 1:FileNames_len
uitreenode(app.Tree, 'Text', cell2mat(VecFiles(jj)), 'NodeData', []);
end
% 判断当前路径下是否有文件夹,如果有,则新建父节点,并用当前目录下的文件夹名来命名父节点。
[Folders_len, ~] = size(VecFolders);
if Folders_len ~= 0
for ii = 1:Folders_len
%%%%%%%%%%%%%%%%%%%%%%%%%%
% 创建一级节点(父节点)
category1 = uitreenode(app.Tree, 'Text', cell2mat(VecFolders(ii)), 'NodeData', []);
folder_path1 = [pathname, '\', cell2mat(VecFolders(ii))]; % 保存当前目录的文件夹路径
File1 = dir(folder_path1); % 查找当前文件夹路径下的所有文件
FileNames1 = {File1.name}'; % 提取所有文件的文件夹名,转换为n行1列
[FileNames1_len, ~] = size(FileNames1);
subFolders_num = 0;
for jj = 3:FileNames1_len % 排除.和..
%%%%%%%%%%%%%%%%%%%%%%%%%%
% 在父节点下,创建二级节点(子节点)
if File1(jj).isdir % 判断是否为文件夹
subFolders_num = subFolders_num + 1;
else
uitreenode(category1, 'Text', cell2mat(VecFolders(ii)), 'NodeData', []);
end
end
end
end
app.Label.Text = pathname; % 将文件夹路径保存到文本框中
end
end
22、选中任意app.Tree中的(.xlsx)或(.csv),将其数据显示在app.UITable中
- 点击app.Tree,鼠标右键。回调 - 添加SelectionChangedFcn 回调
function TreeSelectionChanged(app, event)
selectedNode = app.Tree.SelectedNodes;
if isempty(selectedNode.Children) % 如果选中的节点无子节点
filename = selectedNode.Text; % 从节点文本中获取文件名
FileName = [app.Label.Text, '\', filename]; % 获取文件的路径和文件夹名
[file_data] = readtable(FileName); % 读取数据
app.UITable.Data = file_data; % 将数据显示在UITable中
app.UITable.ColumnName = file_data.Properties.VariableNames;
end
end
22、点击关闭按钮(跳出提示框)
- 组件浏览器:app.UIFigure - 鼠标右键 - 回调 - 添加CloseRequestFcn 回调
function UIFigureCloseRequest(app, event)
msg = 'Are you sure you want to close ?'; % 显示对话框
% uiconfirm:创建确认对话框。
selection = uiconfirm(app.UIFigure, msg, 'Confirm Close', 'CloseFcn', @app.confirmClose);
if(selection == "确定")
delete(app); % 关闭APP界面
end
end
(3.3)ls 列出当前文件夹的指定内容
ls % 列出当前文件夹的所有内容;
ls m* % 使用 '*' 通配符来匹配模式;
(1)ls *.m % 列出扩展名为 .m 的所有文件和文件夹;
(2)ls m* % 列出名称以字母 m 开头的所有文件和文件夹;
% 备注:该方法不可以赋值操作,否则报错。如:c = ls m*
list = ls('name'); % 在当前文件夹中,返回与指定 name 匹配的文件和文件夹的名称。
(3.4)contains 确定(字符串)中是否有指定的模式(元素)
TF1 = contains(str, pat); % 如果 str 包含指定的模式,将返回1(true),否则返回0(false);
TF2 = contains(str, pat, 'IgnoreCase', true); % 在确定 str 是否包含 pat 时将忽略大小写;
% 举例:str = ["Mary Ann Jones", "Paul Jay Burns", "John Paul Smith", PAUL];
% pat = "Paul";
% TF1 = contains(str, pat); % TF1 = [0, 1, 1, 0];
% TF2 = contains(str, pat, 'IgnoreCase', true); % TF2 = [0, 1, 1, 1];
(3.5)ismember 判断数据 A 的元素是否在 B 中
Lia = ismember(A, B); % 判断数据 A 的元素是否在 B 中
[Lia, Locb] = ismember(A, B); % 确定 A 的哪些元素同时也在 B 中及其在 B 中的相应位置。
(3.6)压缩包提取函数:tar / untar
(1)tar('tarfilename', 'filenames'); % 将 filenames 进行文件压缩,压缩后的压缩包名称为 tarfilename,以(.tar)格式结尾。
(2)untar('mytar_files', 'tar_path'); % mytar_files 表示压缩包路径(包括文件名+后缀),tar_path表示解压缩后的文件保存路径(不包括文件名) ;
例如:untar('C:\Desktop\RawData.tar.gz', 'C:\Desktop');
(3.7)消息提示框:msgbox
errordlg('没有选择文件,请重新选择 !', '错误');
msgbox(error_folder, '加载的数据不符合要求', 'Error');
(3.8)dlwrite 将矩阵写到字符分隔开的文本文件(.txt)中
% 分隔符:(1)逗号:','; (2)空格:' '; (3)制表符:'\t';
(1)dlwrite(Filename, M);
% 将矩阵 M 导出到 Filename 中,分隔符默认为逗号','
(2)dlmwrite(fileName, M, 'delimiter', '\t', 'precision', 6);
% 将矩阵 M 导出到 fileName 中,分隔符为制表符'\t',有效数位为6位(整数位+小数位,小数点位不算) ;
(四)
(4.1)字符串拼接 —— 可同时拼接N个字符串
(1) str = strcat(num2str(100), '万', '不够花');
(2) str = ['C:\Users\pc\Desktop', '\RawData.tar.gz', num2str(1)];
(4.2)比较字符串函数:strcmp、strcmpi、strncmp、strncmpi
(1)strcmp(s1, s2); % 比较字符串(区分大小写)
(2)strcmpi(s1, s2); % 比较字符串(不区分大小写)
(3)strncmp(s1, s2, n); % 比较字符串的前 n 个字符(区分大小写)
(4)strncmpi(s1, s2, n); % 比较字符串的前 n 个字符(不区分大小写)
(4.3)不同数据类型转换函数
cell2table(a) % 将(元胞)cell转换为(表)table
cell2mat(a) % 将(元胞)cell转换为(矩阵)mat
table2cell(a) % 将(表)table转换为(元胞)cell
num2cell(a) % 将(数值)num转换为(元胞)cell
mat2str(a) % 将(矩阵)mat转换为(字符串)str
num2str(a) % 将(数值)num转换为(字符串)str
array2table(a) % 将(数组)array转换为(表)table
char(a) % 将(元胞)cell转换为(字符)char 如:char({12));,将元胞{12}转换为字符串'12'
str2double(a) % 将(字符)char转换为(数值)double
cellstr(a) % 将(字符)char转换为(元胞)cell 如:cellstr(' ');,将'空char类型'转换为'空cell类型'
T = timetable2table(TT) % 将时间表转换为表 如:Time = datetime({'2015-12-18'});
TT = table2timetable(T) % 将表转换为时间表
% 常用的复合型转换
cell2table(num2cell(A)) % 将(数值)num 转化为(表)table(num - cell - table)
cell2mat(table2cell(A)) % 将(表)table 转化为(数值)num(table - cell - num)
(4.4)精确求取 datetime 类型数据中的" 年/月/日/小时/分钟/秒 "
time(1) = num2str(year(temp_datetime)); % 求出内部格式日期的年
time(2) = num2str(month(temp_datetime)); % 求出内部格式日期的月
time(3) = num2str(day(temp_datetime)); % 求出内部格式日期的天
time(4) = num2str(hour(temp_datetime)); % 求出内部格式日期的小时
time(5) = num2str(minute(temp_datetime)); % 求出内部格式日期的分钟
time(6) = num2str(second(temp_datetime)); % 求出内部格式日期的秒
(4.5)获取矩阵的长度/宽度/元素个数/维度数
length(A) % 获得矩阵中(长度或宽度)的最大值,多维矩阵同理,空矩阵长度为0;
height(A) % table表行数,备注:仅限于Matlab中的table类型数据使用
width(A) % table表列数,备注:仅限于Matlab中的table类型数据使用
[m, n] = size(A) % 获得矩阵的行数与列数
numel(A) % 获得矩阵的所有元素个数
ndims(A) % 获得矩阵的维度数
(4.6)查找(非)零元素的索引和值:kind
[row, col] = find(X); % 返回数据 X 中所有非零元素对应的(索引)。
[row, col, v] = find(X); % 返回数据 X 中所有非零元素对应的(索引和值)。
k = find(~X) % 对数组 X 使用逻辑 not 运算符以查找零值(得到对应的索引)。
k = find( X < 10, 5 ) % 查找矩阵 X 中前五个小于 10 的元素(得到对应的索引)。
k = find( y == 0.3 ) % 查找特定的整数值(得到对应的索引)。
(五)
(5.1)行连接符( … ) —— 存在于每行代码最后,将多行代码连接成一行;
例如:c = a/3 + num + b*9 - 15;
代码行1:c = a/3 + num + ...
代码行2: b*9 ...
代码行3: -15;
(5.2)计算 log10(x)、ln(x)、exp(x)
log10(x) % lg(x)
log(x) % ln(x)
exp(1) % e
exp(5) % e^5
(5.3)均值函数:mean(A)
M = mean(A); % 如果 A 为矩阵,则 mean(A) 返回包含每列均值的行向量。
(5.4)SD标准差函数:stdA)
S = std(A); % 如果 A 为矩阵,则 std(A) 返回包含每列标准差的行向量。
(5.5)CV变异系数 —— 标准差与平均值之比
CV 又叫变异系数、离散系数、相对偏差(rsd);用百分数表示。
(1) cv = sd_value / mean_value * (100%)
(2) cv_sequence = SD_sequence ./ Mean_sequence;
% 点除:如果a、b是矩阵,a./b就是a、b中对应的每个元素相除,得到一个新的矩阵。
(5.6)排序函数:sort(A)
[B, ind] = sort(A) % 升序(从小到大),B是A排序后的向量,A保持不变;ind是B中每一项对应于A中项的索引。
神奇BUG在副本卡BOSS
(1)任务描述:将mat数组转换为table类型:table(A)
报错提示:错误使用 writetable —— 位置1的索引超出数组范围(不能超过1)。
备注:" 位置x "指的就是数组的第x维。
原因分析:table 里面的每一个数据都是一个 table,而内部 table 的数据全为数字。
(2)任务描述:将全为数字的元胞cell转换为mat格式:cell2mat(A)
报错提示:错误使用 cat 要串联的数组的维度不一致。
原因分析:cell 数组中,每个元胞中存储的格式并非 double,而是 char 数组,而且每一行char的长度不一致。
- 情况1:cell 数组中存储的都是 double 类型,只不过都以 char 类型显示。
– 解决方案:A = cellfun(@str2num, A) 即将所有的 char 类型数组循环采用 str2num(A) 进行格式转换。- 情况2:cell 类型中存储的既有 double 类型也有 char(英文等等),但都以 char 类型显示。
– 解决方案:该情况不应成立。且 char(英文等等)转换为 double 类型时,必定存在数据丢失。
更多推荐
所有评论(0)