matlab

2024-08-05 10:20:48 浏览数 (2)

toc

机器学习

pinv():求广义逆

在matlab中不同行列数的矩阵相加时会先进行运算达到相同的行列数再相加

pwd:显示当前工作路径

nargin:是用来判断输入变量个数

demo:在帮助浏览器中访问产品示例

fft():快速傅里叶变换

extractAfter():提取指定位置后的子字符串

代码语言:bash复制
> > a=["1234";"1256";"1278"];

> > f=extractAfter(a,"12")
代码语言:bash复制
f =

3×1 string 数组

    "34"


    "56"


    "78"

matlab、python矩阵导入ArcGIS(绘制空间图)

对于一些nc数据或者遥感影像处理时,虽然一些第三方软件可以出图,但我们往往需要借助python或者matlab软件进行数据处理,但最后保存下来数据如何导入arcgis进行分析呢?

解决办法

存为txt文件或者dat文件。

代码语言:matlab复制
% 将result变量保存为result.dat
save result.dat result -ASCII;

保存结果(以提取黄河流域mask为例,图中1就是提取出的流域,已存为txt格式数据)

对应关系

变量

对应含义

ncols

列数

nrows

行数

xllcorner

起始经度

yllcorner

起始维度

cellsize

格网的空间分辨率,以上面为例就是分辨率为0.0833333

NODATA_value

代表没有数据的值,通常为-999等,还是看别人当初怎么定义的

注意:
  1. NODATA_value不能是nan,如果是nan值,建议转换为-999再导入arcgis中,否则会报错。

2.matlab读取nc行列会倒过来,所以处理的过程中需要调整。

代码语言:matlab复制
% 行列互换一下
dom=permute(precipitation,[2 1 3]);
precipitation1 = dom(:,:,1);

ncols = size(precipitation, 1);  % 列数
nrows = size(precipitation, 2);  % 行数

precipitation1(isnan(precipitation1))=-999;

python代码

代码语言:python代码运行次数:0复制
# -*- coding:utf-8 -*-
# @author:Ye Zhoubing
# @datetime:2024/5/16 9:35
# @software: PyCharm
# todo:claude转换的代码,后面可以修改
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import xlwt

import numpy as np
from scipy.stats import gamma

file = r"D:yzbPrecipitation_dataPCRGLOBWBPre_poyang.nc"

data = Dataset(file, 'r') # 读取nc文件,默认就是读,这里r可以省略

# print(data) # 可以查看到变量
# 读取相关变量
lat = data.variables['lat'][:].data  # 读取纬度
lon = data.variables['lon'][:].data  # 读取经度
time = data.variables['time'][:].data   # 读取时间
discharge = data.variables['precipitation'][:].data   # todo:这里要根据你nc文件改读取流量,流量discharge三维,分别为层数(时间),纬度、经度

discharge1 = discharge[0]  # 现在就显示第一层的数据


for i in range(discharge1.shape[0]):  # 行
    for j in range(discharge1.shape[1]):  # 列
        if discharge1[i, j] == -999000000.0:  # todo:同样,这里无值的值也要对应修改
            discharge1[i, j] = -9999

# 保存为ASCIII编码的txt文件
np.savetxt('poyang_SRI.txt', discharge1)

# 写入其他数据
nrows = discharge1.shape[0]
ncols = discharge1.shape[1]
xllcorner = min(lon)
yllcorner = min(lat)
cellsize = 0.083333
NODATA_value = -9999

str1 = "nrows         "   str(nrows)   "n"
str2 = "ncols         "   str(ncols)   "n"
str3 = "xllcorner         "   str(xllcorner)   "n"
str4 = "yllcorner         "   str(yllcorner)   "n"
str5 = "cellsize         "   str(cellsize)   "n"
str6 = "NODATA_value         "   str(NODATA_value)   "n"

# 将上述字符串写入poyang_SRI.txt文件头中
with open('poyang_SRI.txt', 'r') as f:
    lines = f.readlines()
    lines.insert(0, str1)
    lines.insert(1, str2)
    lines.insert(2, str3)
    lines.insert(3, str4)
    lines.insert(4, str5)
    lines.insert(5, str6)

with open('poyang_SRI.txt', 'w') as f:
    f.writelines(lines)

print("over")

另外一种方式:参考博客

在arcgis中ASCII转栅格(ASCII to Raster)

后面根据需要进行后续操作,比如我的需要重分类一下才能看出区别。

示例程序

代码语言:matlab复制
clc;close all;clear;
filename1="D:valiPre_poyang_yearsum_mm.nc";

lat = ncread(filename1, 'lat'); %读入变量lat
lon = ncread(filename1, 'lon'); %读入变量lon
time = ncread(filename1, 'time'); %读入时间
precipitation = ncread(filename1, 'precipitation'); %读入单层降水量

% 行列互换一下
dom=permute(precipitation,[2 1 3]);
precipitation1 = dom(:,:,1);
% precipitation1 = precipitation(:,:,1);
precipitation1(isnan(precipitation1))=-999;

% 将precipitation数据保存为txt文件
save('D:valiPre_poyang_yearsum_mm.txt', 'precipitation1', '-ascii');

% 定义要添加的内容
% ncols = size(precipitation, 2);  % 列数
% nrows = size(precipitation, 1);  % 行数
% 因为之前颠倒了,所以行列是反的
ncols = size(precipitation, 1);  % 列数
nrows = size(precipitation, 2);  % 行数
xllcorner = min(lon);  % 起始经度
yllcorner = min(lat);  % 起始纬度
cellsize = 0.08333333;  % 单元大小
NODATA_value = -999;  % 无效值
content = ["ncols         "   ncols;
           "nrows         "   nrows;
           "xllcorner     "   xllcorner;
           "yllcorner     "   yllcorner;
           "cellsize      "   cellsize;
           "NODATA_value  "   NODATA_value;];

% 读取原始文件内容
filename = 'D:valiPre_poyang_yearsum_mm.txt';  % 替换成你的文件名
fid = fopen(filename, 'r');
originalContent = fread(fid, '*char');
fclose(fid);

% 将内容写入新文件
newFilename = 'new_file.txt';  % 替换成输出的新文件名
fid = fopen(newFilename, 'w');
% 将内容写入新文件
fprintf(fid, '%sn', content');

% 将原始文件内容写入新文件
fwrite(fid, originalContent', 'char');
fclose(fid);

参考博客1

参考博客2

补充

查看变量类型:

双击工作区变量或

代码语言:bash复制
> > A=1

A =

     1

> > who

您的变量为:

A    ans

> > whos

Name      Size            Bytes  Class     Attributes

A         1x1                 8  double

ans       1x1                 8  double

在matlab中默认显示小数点后四位,可以通过format

> > format long

> > pi

ans =

3.141592653589793

rat:分数表示

> > 1/3

ans =

0.333333333333333

> > format rat

> > 1/3

ans =

       1/3     

meshgrid:网格

1、主要使用的函数为[X,Y]=meshgrid(xgv,ygv);

meshgrid函数生成的X,Y是大小相等的矩阵,xgv,ygv是两个网格矢量,xgv,ygv都是行向量。

X:通过将xgv复制length(ygv)行(严格意义上是length(ygv)-1行)得到

Y:首先对ygv进行转置得到ygv',将ygv'复制(length(xgv)-1)次得到。

例如

代码语言:bash复制
[X,Y] = meshgrid(1:3,10:14)

X =

     1     2     3


     1     2     3


     1     2     3


     1     2     3


     1     2     3

Y =

    10    10    10


    11    11    11


    12    12    12


    13    13    13


    14    14    14

size:获取数组的行数和列数

length:数组长度(即行数或列数中的较大值)

 Color:线条颜色

LineStyle: 线型

LineWidth: 线宽

Marker: 点型

MarkerSize: 点的大小

MarkerFaceColor: 点的内部颜色

power与.^相同

power(a,b)相当于a.^b

代码语言:javascript复制
set(gca,'xtick',-pi:pi/2:pi) %%设置x轴间隔为半个圆周率,但会显示数
代码语言:javascript复制
set(gca,'xticklabel',{'-pi','-pi/2','0','pi/2','pi'}) %%显示标签,显示pi
代码语言:javascript复制
input(sprintf("请输入%d月的值:",i));%将数据格式化为字符串或字符向量
代码语言:javascript复制
num = xlsread(filename) 读取名为 filename 的 Microsoft® Excel® 电子表格工作表中的第一个工作表,并在一个矩阵中返回数值数据。

num = xlsread(filename,sheet) 读取指定的工作表。

num = xlsread(filename,xlRange) 从工作簿的第一个工作表的指定范围内读取数据。使用 Excel 范围语法,例如 'A1:C3'。

num = xlsread(filename,sheet,xlRange) 读取指定的工作表和范围。

num = xlsread(filename,sheet,xlRange,'basic') 在 basic 导入模式下读取电子表格中的数据。如果您的计算机未安装 Windows® 版 Excel 或者您正在使用 MATLAB® Online™,xlsread 会自动在 basic 导入模式下运行,该模式支持 XLS、XLSX、XLSM、XLTX 和 XLTM 文件。

如果不指定所有参数,请使用空字符向量 '' 作为占位符,例如,num = xlsread(filename,'','','basic')。

[num,txt,raw] = xlsread(___) 还使用先前语法中的任何输入参数,在元胞数组 txt 中返回文本字段,在元胞数组 raw 中返回数值数据和文本数据。

___ = xlsread(filename,-1) 打开一个 Excel 窗口以便按交互方式来选择数据。选择工作表,将鼠标拖放到所需范围上,然后点击确定。只有安装了 Microsoft Excel 软件的 Windows 计算机才支持此语法。

[num,txt,raw,custom] = xlsread(filename,sheet,xlRange,'',processFcn)(其中 processFcn 是函数句柄)读取电子表格,对数据调用 processFcn,并在数组 num 中以数值数据的形式返回最终结果。xlsread 函数在元胞数组 txt 中返回文本字段、在元胞数组 raw 中返回数值和文本数据,并在数组 custom 中返回 processFcn 的第二个输出。xlsread 函数不会更改电子表格中存储的数据。只有安装了 Excel 软件的 Windows 计算机才支持此语法。

scatter 散点图

 1)  pdf:用于生成各类概率分布的PDF 概率密度函数

2)  cdf:用于生成各类概率分布的CDF 累积分布函数

3)   icdf:用于生成各类概率分布的inverse CDF

4)   random:用于生成各类概率分布的随机数

5)   fitdist:用于生成各类概率分布拟合给定随机数据的统计参数(如均值、方差)

Copula函数描述的是变量间的相关性,实际上是一类将联合分布函数与它们各自的边缘分布函数连接在一起的函数,因此也有人将它称为连接函数。

多行注释:%{

需要注释不执行的若干命令行

%}       

matlab与excel结合使用

1.获取excel文件中所有sheet

代码语言:matlab复制
% 获取所有的工作表名称
[~,sheets] = xlsfinfo(excel_file);

2.写入excel文件xlswrite

xlswrite(strcat('result', '\', '周期.xlsx'), num2cell(T)', stationname, ['A2:' char('A' numCols - 1) '2']);

matlab中调用python程序

有时需要在matlab中执行python程序,比如matlab程序完成想用企业微信通知

1.检查环境

代码语言:bash复制
% 检查Matlab能否调用Python
> pyversion

%如果不能调用python,可以给定python的可执行路径。如:
> pyversion('f:Anaconda3python.exe')
% 上面路径根据情况更改即可。

结果:

代码语言:bash复制
>> pyversion

       version: '3.9'
    executable: 'C:Users32649AppDataLocalProgramsPythonPython39python.EXE'
       library: 'C:Users32649AppDataLocalProgramsPythonPython39python39.dll'
          home: 'C:Users32649AppDataLocalProgramsPythonPython39'
      isloaded: 0

要注意自己的matlab版本是否与python版本兼容

2.调用程序中的def或者class

建议正式调用前,先在matlab中添加路径(也就是.py文件所在位置):

代码语言:matlab复制
    % 添加python的搜索路径
    P = py.sys.path; 
    if count(P,'E:/XXX/XXX.py') == 0
       insert(P,int32(0),'E:/XXX/XXX.py');
    end

然后在matlab中测试.py文件(也就是模块module)是否包含错误:

代码语言:matlab复制
    % 假设调用的.py文件的名称为:myfun.py
    >> py.importlib.import_module('myfun')

有错误可能py文件中程序有问题

调用函数

假如我的.py文件为:

代码语言:python代码运行次数:0复制
    # myfun.py
    def add(a, b):
        c = a   b
        return c

里面有一个add函数。那么,我们就可以直接用下面的代码 在matlab调用python:

代码语言:matlab复制
    % 在matlab中输入下面语句,调用.py的add函数
    >> py.myfun.add(1,2)

里面ans返回的便是3

调用类

假如我的.py文件为:

代码语言:python代码运行次数:0复制
    class myclass():
        def __init__(self):
            self.count = 0
        def fit(self,X):
            XXX 代码省略  XXX
            print('count = ', self.count)
            return G

里面有类 myclass.那么,我们就可以直接用下面的代码 在matlab调用python的类:

代码语言:matlab复制
    % 前面的测试
    py.importlib.import_module('myfun')
    
    % 需要实例化类。其中,myfun为.py文件的名称,myclass类名。
    myRCD = py.myfun.myclass;
    
    % 根据需要将输入的数据 转换为一维的numpy形式,方便调用。
    X = py.numpy.array(X(:).'); 
    
    % 调用实例化类myRCD的函数 fit 
    myRCD.fit(X);
    
    % 根据需要把输出换成matlab的形式
    GG = double(myRCD.adjacency_matrix_);

3.重载

一旦.py文件修改的话,就在matlab用以下代码更新一下就可以啦,不用重启matlab:

代码语言:matlab复制
    clear classes;
    obj = py.importlib.import_module('rcd');
    py.importlib.reload(obj);

自己的例子

调用def

代码语言:matlab复制
clear classes
obj = py.importlib.import_module('test'); % 导入test.py文件,这里写的是相对路径,可以用绝对路径
py.importlib.reload(obj);
py.test.add(1,2);  % 给test传入参数,python中的print内容貌似不会出现在matlab控制台

调用class

代码语言:matlab复制
    %% 调用类class,企业微信发送消息
    % 前面的测试
    py.importlib.import_module('WeChat_send');
    
    % 需要实例化类。其中,WeChat_send为.py文件的名称,SendWeixin类名。
    myRCD = py.WeChat_send.SendWeixin('标题', '测试内容');
    
    % 调用实例化类myRCD的函数main
    myRCD.main('YeZhoubing');  % 传入参数id为YeZhoubing

WeChat_send.py文件如下图

注意:

python跟matlab相互调用其实蛮坑的,建议还是用单一语言环境。在调用过程中指不定哪里就会出现问题。

初级

clc:清屏命令行内容

新建脚本:CTRL N,此时预设可以打开,调整自己想要调整的内容

  采用块注释方法,MATLAB块注释使用的语句与C语言不同。MATLAB使用如下格式:%{         注释代码

%}

log()表示ln()

变量命名:

clear all/clear:清楚右侧工作区内容

matlab中%表示注释,%%(cell模式)标识一块代码,可以折叠

abs(),求()中的值的ascii值

char(),表示转换成字符

num2str(),把数值转换成字符串, 转换后可以使用fprintf或disp函数进行输出。在matlab命令窗口中键入doc num2str或help num2str即可获得该函数的帮助信息。

length(),计算字符串长度

矩阵:A = 1 2 3; 4 5 2; 3 2 7

代码语言:bash复制
A =

     1     2     3


     4     5     2


     3     2     7

>> B=A'    将A矩阵转置,行变为列,列变为行

B =


     1     4     3


     2     5     2


     3     2     7

>> C=A(:)   矩阵按列拉伸

C =

     1


     4


     3


     2


     5


     2


     3


     2


     7

逆矩阵:设A是一个n阶矩阵,若存在另一个n阶矩阵B,使得: AB=BA=E ,则称方阵A可逆,并称方阵B是A的逆矩阵

>> D=inv(A)   计算方阵 A的 逆矩阵。A^(-1) 等效于 inv(A)

D =

   -0.9118    0.2353    0.3235


    0.6471    0.0588   -0.2941


    0.2059   -0.1176    0.0882

即:>> A*D

ans =

    1.0000         0    0.0000


    0.0000    1.0000    0.0000


    0.0000         0    1.0000

>> E=zeros(10,5,3)   一个三维的E矩阵,10行5列,赋值为0

E(:,:,1) =

     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0

E(:,:,2) =

     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


E(:,:,3) =


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0


     0     0     0     0     0

1.rand生成均匀分布的伪随机数。分布在(0~1)之间

rand(m,n)生成m行n列的均匀分布的伪随机数

rand(m,n,'double')生成指定精度的均匀分布的伪随机数,参数还可以

是'single'

rand(RandStream,m,n)利用指定的RandStream(我理解为随机种子)生成伪随机数

2.randn生成标准正态分布的伪随机数(均值为0,方差为1)

randn(RandStream,m,n)利用指定的RandStream生成1伪随机数,rand有其相同用法

3.randi生成均匀分布的伪随机数,randi()函数生成均匀分布的伪随机整数,范围为imin--imax,如果没指定imin,则默认为1

randi(iMax)在开区间(0,iMax)生成均匀分布的伪随机整数

randi(iMax,m,n)在开区间(0,iMax)生成mXn型随机矩阵

r = randi(iMin,iMax,m,n)在开区间(iMin,iMax)生成mXn型随机矩阵

E(:,:,1) =rand(10,5) 10行5列值在0~1之间

E(:,:,2) =randi(5,10,5) 10行5列,最大值是5

E(:,:,3) =randn(10,5) 10行5列伪随机数

代码语言:bash复制
E(:,:,1) =

    0.8147    0.1576    0.6557    0.7060    0.4387


    0.9058    0.9706    0.0357    0.0318    0.3816


    0.1270    0.9572    0.8491    0.2769    0.7655


    0.9134    0.4854    0.9340    0.0462    0.7952


    0.6324    0.8003    0.6787    0.0971    0.1869


    0.0975    0.1419    0.7577    0.8235    0.4898


    0.2785    0.4218    0.7431    0.6948    0.4456


    0.5469    0.9157    0.3922    0.3171    0.6463


    0.9575    0.7922    0.6555    0.9502    0.7094


    0.9649    0.9595    0.1712    0.0344    0.7547


E(:,:,2) =

     2     4     5     2     1


     4     2     2     5     1


     4     3     5     3     3


     1     4     2     3     4


     1     5     5     5     5


     3     5     2     2     1


     5     3     1     4     3


     2     1     2     4     3


     3     1     4     2     1


     2     2     3     3     2

E(:,:,3) =

   -1.7947   -0.1941   -1.2078   -2.0518   -0.2991


    0.8404   -2.1384    2.9080   -0.3538    0.0229


   -0.8880   -0.8396    0.8252   -0.8236   -0.2620


    0.1001    1.3546    1.3790   -1.5771   -1.7502


   -0.5445   -1.0722   -1.0582    0.5080   -0.2857


    0.3035    0.9610   -0.4686    0.2820   -0.8314


   -0.6003    0.1240   -0.2725    0.0335   -0.9792


    0.4900    1.4367    1.0984   -1.3337   -1.1564


    0.7394   -1.9609   -0.2779    1.1275   -0.5336


    1.7119   -0.1977    0.7015    0.3502   -2.0026

元胞数组:

代码语言:bash复制
>> A=cell(1,6)    创建1行6列的元胞数组

A =

  1×6 cell 数组

  列 1 至 5
    {0×0 double}    {0×0 double}    {0×0 double}    {0×0 double}    {0×0 double}

  列 6

>> A{2}=eye(3)    matlab下标从1开始

A =

  1×6 cell 数组

  列 1 至 5

    {0×0 double}    {3×3 double}    {0×0 double}    {0×0 double}    {0×0 double}

  列 6

    {0×0 double}

>> A{5}=magic(5)   magic在matlab中生成n阶幻方,例如三阶幻方就是3 x 3矩阵用1-9数字使横、竖、斜和相等

A =

  1×6 cell 数组

  列 1 至 5

    {0×0 double}    {3×3 double}    {0×0 double}    {0×0 double}    {5×5 double}

  列 6

    {0×0 double}

>> B=A{5}    查看A{5}的值

B =

    17    24     1     8    15


    23     5     7    14    16


     4     6    13    20    22


    10    12    19    21     3


    11    18    25     2     9

结构体:类似字典

代码语言:bash复制
>> books=struct('name',{{'machine','data'}},'price',[30,40])   这里的数据要用大括号括起来,外面的大括号表示整个是一个元胞数组

books = 

  包含以下字段的 struct:

     name: {'machine'  'data'}

    price: [30 40]

>> books.name   在books中的name属性

ans =

  1×2 cell 数组

    {'machine'}    {'data'}

>> books.name(1)  值为cell

ans =

  1×1 cell 数组

    {'machine'}

>> books.name{1} 值为字符串

ans =

    'machine'

>> B=1:2:9     在1~9之间加2

B =

     1     3     5     7     9

>> C=repmat(B,3,1)    将B重复3行1列(竖着的重复3次横着的重复1次)

C =

     1     3     5     7     9


     1     3     5     7     9


     1     3     5     7     9

>> D=ones(2,4)   生成2行4列的矩阵,同时值为1(与zeros类似)

D =

     1     1     1     1


     1     1     1     1

矩阵四则运算:

代码语言:bash复制
>> A=[1,2,3,4;5,6,7,8]

B=[2,2,3,4;5,6,7,8]

A =

     1     2     3     4


     5     6     7     8

B =

     2     2     3     4


     5     6     7     8

>> C=A.*B      .表示对应位置进行运算

C =

     2     4     9    16


    25    36    49    64

>> E=A./B

E =

    0.5000    1.0000    1.0000    1.0000


    1.0000    1.0000    1.0000    1.0000

矩阵下标:

>> B=A(2,3)    B取A(5阶幻方)第2行3列的元素

B =

     7

>> C=A(3,:)     :表示所有,故取3行所有元素

C =

     4     6    13    20    22

>> D=A(:,4)   第四列所有元素

D =

     8


    14


    20


    21


     2

>> [m,n]=find(A>20)   在A矩阵中大于20的元素位置,m表示行,n表示列

m =

     2


     1


     5


     4


     3

n =

     1


     2


     3


     4


     5

程序结构:

求1~5的2平方和

代码语言:matlab复制
%%for 循环变量=初值:步进:终值

     循环语句

end

步进值默认为1,可以省略

代码语言:bash复制
>> sum=0

sum =

     0

>> for n=1:1:5       1:5


sum=sum n^2


end

sum =

     1

sum =

     5


sum =

    14

sum =

    30

sum =

    55
代码语言:bash复制
while  条件表达式

循环语句

end
代码语言:bash复制
if  条件表达式

执行语句

end


if  条件表达式

执行语句1

else

执行语句2

end

switch 表达式

case1

语句1;

case2

语句2;

otherwise

语句n

end

二维平面绘图:

代码语言:matlab复制
x=0:0.01:2*pi;%pi表示圆周率


y=sin(x);


figure%建立一个幕布


plot(x,y) %绘制二维平面图


title("y=sin(x)函数图像")  %有的地方需要区分“ 与‘,添加图名


xlabel("x")  %添加x轴名称


ylabel("sin(x)") %添加y轴名称


xlim([0 2*pi]) %x轴范围设为0~2倍圆周率
代码语言:matlab复制
x=0:0.01:20;


y1=200*exp(-0.05*x).*sin(x);  %exp(1)相当于e^1


y2=0.8*exp(-0.5*x).*sin(10*x);


figure   %默认有


[AX,H1,H2] = plotyy(x,y1,x,y2,'plot'); %Plotyy() 带有两套y坐标轴的线性坐标系,返回三个参数,AX是坐标轴的句柄,AX(1) 是左边的纵zhi轴, AX(2) 是右边的纵轴;H1和 H2保存的是图形句柄;和set相关;


set(get(AX(1),'Ylabel'),'String','Slow Decay') %set用来设置坐标轴的形式,名字或刻度线等等;AX(1)就是设置左边的纵轴;


set(get(AX(2),'Ylabel'),'String','Fast Decay') %set(句柄,属性名1,属性值1,属性名2,属性值2,…)


xlabel('Time (musec)') %设置x轴名字


title('示例图')


set(H1,'LineStyle','--') %设置线型


set(H2,'LineStyle',':')


set(H1,'color','b') %设置颜色


set(H2,'color','r')


%%


1.plotyy(X1,Y1,X2,Y2):以左、右不同纵轴绘制X1-Y1、X2-Y2两条曲线。


2.plotyy(X1,Y1,X2,Y2,FUN1):以左、右不同纵轴把X1-Y1、X2-Y2两条曲线绘制成FUN1指定形式的两条曲线。


3.plotyy(X1,Y1,X2,Y2,FUN1,FUN2):以左、右不同纵轴把X1-Y1、X2-Y2两条曲线绘制成FUN1、FUN2指定的不同形式的两条曲线。


4.[AX,H1,H2]=plotyy(...):返回AX中创建的两个坐标轴的句柄以及H1和H2中每个图形绘图对象的句柄。AX(1)为左侧轴, AX(2)为右侧轴。


  %%

改进:

代码语言:matlab复制
x = 0:0.01:20;

y1 = 200*exp(-0.05*x).*sin(x);

y2 = 0.8*exp(-0.5*x).*sin(10*x);

[AX,H1,H2] = plotyy(x,y1,x,y2,'plot');

set(AX(1),'Xcolor','k','YColor','b');

set(AX(2),'XColor','k','YColor','r');

HH1=get(AX(1),'Ylabel');

set(HH1,'String','Left Y-axis');

set(HH1,'color','b');

HH2=get(AX(2),'Ylabel');

set(HH2,'String','Right Y-axis');

set(HH2,'color','r');

set(H1,'LineStyle','-');

set(H1,'color','b');

set(H2,'LineStyle',':');

set(H2,'color','r');

legend([H1,H2],{'y1 = 200*exp(-0.05*x).*sin(x)';'y2 = 0.8*exp(-0.5*x).*sin(10*x)'});

xlabel('Zero to 20 musec.');

title('Labeling plotyy');

三维绘图:

代码语言:matlab复制
t=0:pi/50:10*pi;


plot3(sin(t),cos(t),t) %绘制三维图,对应x,y,z;plot3(x,y,z)是将x,y作为底面plot3(z,y,x)是将z,y作为底面


xlabel('sin(t)')


ylabel('cos(t)')


zlabel('t')


grid on   %打开网格线


axis square  %axis square/将当前坐标系图形设置为方形。横轴及纵轴比例是1:1

图形的保存与导出:

编辑、复制选项中调节图像,图形属性也可以调

编辑,复制图层

或文件另存

这里是像素值,调高避免过小不清晰

x,y,z=peaks(30); %peaks是一bai个函数,其中有2个变du量。由平移和zhi放缩高斯分布函dao数获得。这里输入n(zhuan=30)是说输shu出30*30的矩阵,并显示。Matlab提供了一个peaks函数,可产生一个凹凸有致的曲面,包含了三个局部极大点及三个局部极小点

mesh(x,y,z) %mesh(x,y,z)表示以(x,y,z)绘制三维图

ecdf函数,是求经验分布函数

一些基本的函数

1.uigetfile()

matlab的uigetfile函数可以打开文件对话框,可以选择其中的一个或多个文件,如果文件存在且有效,返回值为文件名和文件所在的路径;如果点击取消或者关闭文件对话框,则返回值为0。

2.fopen()

fileID = fopen(filename,permission,machinefmt,encodingIn)

machinefmt - 读取或写入字节或位的顺序

'n' (默认) | 'b' | 'l' | 's' | 'a' | ...

在文件中读取或写入字节或位的顺序,指定为以下字符向量或字符串标量之一。

Col1

Col2

'n''native'

系统字节排序方式(默认)

'b''ieee-be'

Big-endian 排序

'l''ieee-le'

Little-endian 排序

's''ieee-be.l64'

Big-endian 排序,64 位长数据类型

'a''ieee-le.l64'

Little-endian 排序,64 位长数据类型

默认情况下,当前支持的所有平台都使用 little-endian 排序方式对新文件进行排序。现有二进制文件可以使用 big-endian 或 little-endian 排序方式。

高版本Matlab运行时在当前文件夹或MATLAB路径中未找到文件函数或变量无法识别的解决方法

问题:

有时运行matlab的文件时,弹出更改文件夹或者添加到路径,点击后还是会弹出无法识别

解决方法:

matlab中随便修改一下再保存。

其实就是你第一次保存后Matlab没反应过来,或者说它不认你的第一次保存,无论你的命名方式多么正确。。。出现上述问题只需要重新保存一次就行啦。

NaN

NaN就是not a number的简称,在matlab中,两个NaN的变量相比较,返回的一定是不相等,所以在进行变量的比较的时候,要注意是否是NaN

代码语言:matlab复制
isnan(variable)

在vscode中修改m文件后,在matlab中再修改一次才能运行

出问题的地方:

这个地方不能注释掉,但不注释对于不同的m文件编码会乱码

解决办法

"files.autoGuessEncoding": true,放到最前面,matlab关联的编码的方式不注释

matlab下的并行循环

我们知道,matlab 更适合的处理对象是矩阵,而不是大规模的循环运算。当有时不得不使用 for 循环时,如果提高 for 循环的执行效率呢。这就是 parfor 的用武之地了,既然是并行运算,就是一次可以执行多次 iterations 处理(类似于操作系统的多线程作业),以加快循环的速度。与传统 for 循环最大的不同在于,parfor 执行迭代时并不按照一个确定的顺序(因此,需要求不同的迭代之间,彼此独立,不存在 A(i) = A(i-1)/A(i 1) 的情况,)。

代码语言:matlab复制
i=1:100000;
j=1:100000;
Y=0;
parfor i=1:100000
    for j=1:1:100000
        Y=Y i j;
    end    
end

parfor注意事项?

  • matlab默认是不能在parfor里面使用save函数的。因为matlab不知道要把工作区的哪个变量保存到内存中。但是有时候,你的实验里确实需要保存中间的结果,那么matlab还是有解决方案的:1)你可以将需要保存文件的操作放进另一个函数里进行操作,然后再当前的parfor循环体内调用这个函数parsave1, 2(链接中有具体的代码参考)。2)你也可以不用save的操作,在需要保存的数据后断点,然后自己实现保存操作。
  • 用parfor循环的下标必须为连续的递增整数。 ————————————————图形化使用方法简单步骤如下:

1.点击matlab最底下左边的正三角标号,选择“start parallel pool”(当然用其他方式开启也可以);

2.将符合条件的循环for改成parfor即可开始并行运算。

3.payfor不可循环嵌套

parfor要求循环中的数据没有上下依赖,每个循环之间相互独立,这样才能在多个处理器上运行并行任务。

代码语言:matlab复制
% 读取数据
path1="C:Users32649DesktopnctestBrother 0.1differ_ 0.1.nc";
nlat=double(ncread(path1,'lat')); %读取纬度变量,为二维数据省略meshgrid
nlon=double(ncread(path1,'lon')); %读取经度变量
pr=double(ncread(path1,'discharge')); %获取变量数据
[mlat,mlon]=meshgrid(nlat,nlon);
mkdir('img') %创建img子文件夹
par=parpool('local', 6); %设置6个处理器
% 展示
parfor day=1:size(pr,3) %展示第几层的数据,数据依赖于nc文件,层数代表时间`
    m_proj('miller','lon',[85 131],'lat',[18 38]); %设置投影方式,经纬度范围,经纬度范围可以提前在arcgis中查看(这里对应的经度:85-131;纬度:18-38)
    m_contourf(mlon,mlat,pr(:,:,day),'linestyle','none'); 
    % colormap(flipud(m_colmap('hsv')));%设置颜色legend
    color=cbrewer2('div','RdBu',10,'linear');% 生成PuBu的配色方案的color矩阵,10就是把色带分为10份 
    colormap(color);%将color配色用于colormap
    hold on
    m_coast('line','Color', [.5 .5 .5]);% 只保留轮廓线
    % m_grid('linestyle','none','box','fancy','tickdir','out','LineWidth',0.5); %设置网格
    m_grid %设置网格
    colorbar;
    % set(gca,'CLim',[-60,20]) %指定颜色范围,这里是-60到20
    title(['time: ', num2str(day)]) %设置标题
    hold off
    saveas(gcf, ['img', num2str(day), '.jpg'])
end

参考文章:Matlab并行计算(新手)

退出matlab终端命令

quit或者exit

如果是想要在matlab终端命令行继续执行matlab的文件,直接输入文件名即可,不要.m后缀(要在这个路径下)

Matlab下地形图绘图包m_map安装与使用

m_map是Matlab下用于绘制地图的工具箱,和GMT有些相似。

m_map官网:https://www.eoas.ubc.ca/~rich/mapug.html

下载

进入m_map官网:https://www.eoas.ubc.ca/~rich/mapug.html

下载tar压缩文件或者zip压缩文件。

如何看箱线图

箱线图可以用来反映一组或多组连续型定量数据分布的中心位置和散布范围。

如上图所示,在箱线图中,箱子的中间有一条线,代表了数据的中位数。箱子的上下底,分别是数据的上四分位数(Q3)和下四分位数(Q1),这意味着箱体包含了50%的数据。因此,箱子的高度在一定程度上反映了数据的波动程度。上下边缘则代表了该组数据的最大值和最小值(忽略掉异常值)。有时候箱子外部会有一些点,可以理解为数据中的“异常值”。

四分位数

一组数据按照从小到大顺序排列后,把该组数据四等分的数,称为四分位数。第一四分位数 (Q1)、第二四分位数 (Q2,也叫“中位数”)和第三四分位数 (Q3)分别等于该样本中所有数值由小到大排列后第25%、第50%和第75%的数字。第三四分位数与第一四分位数的差距又称四分位距(interquartile range, IQR),如下图所示。

注:

有时候我们会发现箱形图的某一部分仿佛被隐藏了,除此之外还有一些极端情况,箱子被压得很扁,甚至只剩下一条线,同时还存在着很多异常值。这些情况的出现,有两个常见的原因:

第一,样本数据中,存在特别大或者特别小的异常值,这种离群的表现,导致箱子整体被压缩,反而凸显出来这些异常;

第二,样本数据特别少,因此箱体受单个数据的影响被放大了。

vscode中matlab乱码

2020版本以上时,“问题”框会乱码,此时 // "matlab.linterEncoding": "gb2312",将该行注释掉即可。

修改后的:

注意事项

如果你的matlab是2020版的话,那么它默认是utf-8编码的,而之前的2019/2018…都是GBK编码的

所以如果你按照网络上的那个教程配置matlab与vscode,以gb2312的方式打开必然会导致乱码。

建议2020版本的就不要修改配置文件编码方式了,下好相应的文件即可使用。如下图所示,注释掉这些地方:

matlab使用第三方包

matlab使用第三方包需要将下载的第三方包设置路径

将路径添加进去

例如,现在我有两个文件夹需要,对应文件夹中储存有第三方m文件,步骤如下

1.将文件放入matlab安装目录下的toolbox文件夹中

2.将文件夹路径置于matlab搜索路径中

点击添加文件夹,添加需要的文件夹,例如在github_repo中需要的是cbrewer2文件夹,添加该文件夹即可。

3.调用which命令检查是否修改成功

在控制台使用which 函数名,检验是否添加成功

代码语言:bash复制
>> which cbrewer2
>> which colorspace

matlab程序完成通知

代码语言:matlab复制
% matlab实现调用server酱,注意写英文,中文需要 urlencode 函数
URL='https://sctapi.ftqq.com/SCT102694TtHeicGvqDyKXlXmENiNP023f.send?title=project finish';
str = urlread(URL)

还有是用邮件与短信进行通知,具体可以参考以下的链接

在matlab中计算程序运行时间

注意:三种方法由于计算原理不同,得到的时间结果可能有差异!

1、tic和toc组合(使用最多的)

该方法计算tic和toc之间那段程序之间的运行时间,它的经典格式为:

代码语言:matlab复制
tic
%需要计时的程序代码
……
toc

换句话说,程序中遇到tic时Matlab自动开始计时,运行到toc时自动计算此时与最近一次tic之间运行的时间。最后得到运行时间如下:

在这里插入图片描述

2、etime(t1,t2)并和clock配合

该方法计算t1,t2之间的时间差,它是通过调用windows系统的时钟进行时间差计算进而得到运行时间的,应用格式:

代码语言:matlab复制
t1=clock;
%需要计时的程序代码
……
t2=clock;
etime(t2,t1)

3、cputime函数来完成

使用方法和etime()相似,只是cputime是使用cpu的主频计算时间的,和前面原理不同,使用格式如下:

代码语言:matlab复制
t0=cputime
%需要计时的程序代码
……
t1=cputime-t0

总结

Matlab官方推荐使用tic/toc组合,When timing the duration of an event, use the tic and toc functions instead of clock or etime.

至于大家可以根据自己的喜好选择,但是使用tic/toc的时候一定要注意,toc计算的是与最近一次运行的tic之间的时间,不是程序开始的第一个tic,更不是第二个。

matlab练习nc及一些注意点

代码语言:matlab复制
clc; %清屏
clear all;%清空
%%
%读取数据
% 数据列表
% 梅港 外洲 李家渡 渡峰坑 虎山 万家埠 虬津 九江 湖口
filename1 = "D:文档微信WeChat Fileswxid_n0r37d029t1w22FileStorageFile2022-101(3).nc";
[num,station_list] = xlsread("C:Users32649Desktop拍摄照片(9月27号)水文站位置.xlsx","Sheet2","A2:A10"); % 字符串在station,数值在num
lon_station_list = xlsread("C:Users32649Desktop拍摄照片(9月27号)水文站位置.xlsx","Sheet2","B2:B10");
lan_station_list = xlsread("C:Users32649Desktop拍摄照片(9月27号)水文站位置.xlsx","Sheet2","C2:C10");
for i = 1:length(lan_station_list)
    lon_station = lon_station_list(i); lat_station = lan_station_list(i);
    % ncdisp(filename1);
    ncid1 = netcdf.open(filename1, 'NC_NOWRITE'); %打开nc文件
    lat = ncread(filename1, 'lat'); %读入变量lat
    lon = ncread(filename1, 'lon'); %读入变量lon
    time = ncread(filename1, 'time'); %读入时间
    [lat_2D lon_2D] = meshgrid(lat, lon);
    distance = sqrt((lat_2D - lat_station).^2   (lon_2D - lon_station).^2); %算出站点与每个格点距离
    [ilon ilat] = find(distance == min(min(distance))); %寻找距离最近格点
    lat_back = lat(ilat); %输出lat_back、lon_back经纬度检查是否为希望读取站点
    lon_back = lon(ilon, :);
    % 将找到的经纬度写入sheet2
    writematrix([lat_back lon_back],strcat(station_list{i,1},'.xls'),'Sheet',2); % strcat 串联字符串 station_list(i,1) cell中的第i行1列
    discharge = ncread(filename1, 'discharge');
    blh_station = discharge(ilon, ilat, :);
    discharge_list = squeeze(blh_station); % squzze()删除长度为1的维度,这里是将三维数组转换为一维
    writematrix(discharge_list,strcat(station_list{i,1},'.xls'),'Sheet',1); % TODO: 文件保存有变量名
    netcdf.close(ncid1); %关闭nc文件
    disp(strcat(station_list{i,1},'over'));
    % % ncdisp('C:UserssunxyDesktop200901.nc','/','full')
end

matlab读取nc

由于matlab的读取方式,直接用matlab读取的nc文件行列是颠倒的,所以要转置一下:

代码语言:matlab复制
data1 = ncread('file1.nc', '/'); data_in_permute=permute(data1,[2 1 3]);

matlab写入nc

代码语言:matlab复制
clc;clear;
data1=ncread("C:UsersLenovoDesktopERA5LAND_1961_pr4_monavg_24_China_mm.nc","precipitation");
data2=ncread("C:UsersLenovoDesktoppr61_monavg_mm.nc","precipitation");
data_1_permute=permute(data1,[2 1 3]);
data_2_permute=permute(data2,[2 1 3]);

data = data_1_permute(:,:,7) - data_2_permute(:,:,7);

lat = ncread("C:UsersLenovoDesktoppr61_monavg_mm.nc", 'lat'); %读入变量lat
lon = ncread("C:UsersLenovoDesktoppr61_monavg_mm.nc", 'lon'); %读入变量lon
time = ncread("C:UsersLenovoDesktoppr61_monavg_mm.nc", 'time'); %读入时间

for i = 1:426
    for j = 1:744
        if data(i,j) > 9e 11
            data(i,j) = NaN;
        end
    end
end

nccreate("diff2.nc","precipitation", 'Dimensions', {'lon', length(lat), 'lat', length(lon)});
ncwrite("diff2.nc","precipitation",data);

matlab相关nc程序

1.extract_bin.m

代码语言:matlab复制
%% 生成mask,保存为bin格式文件。

clc;clear;
data2=ncread('E:gradsfileERA5LAND_1950_daymax_2m_temperature.nc','fracWaterInp'); 
data = data2(:,:,1);
data(~isnan(data))=1;
data(isnan(data))=-999000000;
pathmodcort =['E:grads_caozuoresult'];    %修改输出路径!!!!!!!!!!!!!!!!!!!!!!!
fbc_out1 =['mask.bin'];  %修改输出文件名!!!!!!!!!!!!!!!!!!!!!!!

data = reshape(data,[4320 2160 1]);  %这个4320和2160是根据data的格子数来的
dataoutname = strcat(pathmodcort,fbc_out1);
fid = fopen(dataoutname,'w','l');
fwrite(fid,data,'float')
fclose(fid);

2.look_bin.m

代码语言:matlab复制
%% 用于弹出窗口选择文件查看,想要看什么格式文件就修改程序里对应的后缀

XX=4320;%%%%%%%注意修改数据空间栅格数(经度数)!!!!!!!!!!!!!!!
YY=2160;%%%%%%%注意修改数据空间栅格数(纬度数)!!!!!!!!!!!!!!!
[filename,path]=uigetfile('*.bin','Default_name.bin');
    fid1=fopen(strcat(path,filename),'r','l');
    data_obs = fread(fid1,'float');
    fclose(fid1);
    data_obs = reshape(data_obs,[XX YY 1]);

0 人点赞