matlab绘图(2):散点密度图

绘图函数

  1. 绘图效果:
    在这里插入图片描述

  2. 复制粘贴存好plot_scatter.m函数:

function coeff=plot_scatter(x_obs, y_sim, fit_degree,cal_metrics,plot_info)

    % x_obs: 自变量数据
    % y_sim: 因变量数据
    % fit_degree: 多项式拟合的阶数
    % cal_metrics: table,已计算好的拟合评价指标
    % plot_info:table,已存储好的绘图信息

    %% 输入数据预处理
    % 检查输入的 x 和 y 是否具有相同的行列数
    if ~isequal(size(x_obs), size(y_sim))
        error('The sizes of input x_obs and y do not match.');
    end

    % 排除 NaN 值并计算有效元素个数
    valid_indices = ~isnan(x_obs) & ~isnan(y_sim); 
    x_valid = x_obs(valid_indices);
    y_valid = y_sim(valid_indices);

    %% 基本绘图
    [width, height] = deal(plot_info.size(1),plot_info.size(2));
    figure('Units','centimeter','Position',[10 5 width height]);   
    %'Units', 'centimeter': 将图形窗口的单位设置为厘米。
    %'Position', [17 11 8 8]: 设置图形窗口的位置和大小。
    % [17 11 8 8] 表示 [left bottom width height],
    %left = 17 cm;% 窗口左边缘离屏幕左边缘的距离
    % bottom = 11 cm; % 窗口底边缘离屏幕底边缘的距离
    % width = 8 cm; % 窗口的宽度
    % height = 8 cm; % 窗口的高度

    % 计算输入数据横纵坐标范围
    x_range=[min(x_valid),max(x_valid)];
    y_range=[min(y_valid),max(y_valid)];

    % 绘制散点密度图
    CData=density2C(x_valid, y_valid,x_range(1):10:x_range(2),y_range(1):10:y_range(2));
    scatter(x_valid, y_valid,5,'filled','CData',CData);
    cb=colorbar;                          % 显示colorbar
    title(cb, 'ksdensity','FontSize',8,'Fontname','Times New Roman'); % 给颜色条添加标题
    hold on;

    % 普通散点图
%     scatter(x_valid, y_valid,14,[0.1,0.5,0.8])   % 第三个是散点的大小,如果默认的话就写[],不写就会报错
    % [0.8, 0.1, 0.2]: 散点的颜色,使用 RGB 三元组表示。
    % 其中红色成分为 0.8,绿色成分为 0.1,蓝色成分为 0.2,这会生成一个深红色。

    % bin散点密度图
%     p1=binscatter(x_valid, y_valid, 250);
%     colormap(gca, 'parula'); % 设置颜色映射为 'jet'
%     hold on;
 
    % 设置统一坐标轴范围
    axis_range = [min(x_range(1),y_range(1)), max(x_range(2),y_range(2))];
    % 向下取整最小值,向上取整最大值
    axis_range_int = [floor(axis_range(1) / plot_info.ax_d) * ...
        plot_info.ax_d,ceil(axis_range(2) / plot_info.ax_d) * plot_info.ax_d];
    if ismember('range', plot_info.Properties.VariableNames) && ~isempty(plot_info.range)
        axis_range_int=plot_info.range;       
    end
    axis_set=axis_range_int(1):plot_info.ax_d:axis_range_int(2);
    xlim(axis_range_int);
    ylim(axis_range_int);

    % 设置 x 轴和 y 轴的刻度间距
    xticks(axis_set); 
    yticks(axis_set); 

    % 添加趋势线
    coeff = polyfit(x_valid, y_valid, fit_degree);
    y_fit = polyval(coeff, x_valid);
    hold on;
    plot(x_valid, y_fit, 'b-', 'LineWidth', 1);

    %添加1:1回归虚线
    x = axis_set;
    y = x;    % 1:1回归线
    plot(x,y,'r--','linewidth',1)

%% 调试信息
    fit_eq = strcat('\ity\rm=', num2str(coeff(1), '%.2f'), '\itx\rm+', num2str(coeff(2), '%.2f'));
    idx_r2=strcat('\itR\rm^2=', num2str(cal_metrics.r_squared, '%.2f'));
    idx_bias=strcat('BIAS=', num2str(cal_metrics.bias, '%.2f'),plot_info.units);
    idx_rmse=strcat('RMSE=', num2str(cal_metrics.rmse, '%.2f'),plot_info.units);
    idx_n=strcat('N=', num2str(cal_metrics.num_valid));

    % 获取坐标范围
    x_lim = xlim;
    y_lim = ylim;
    [x_frac, y_frac] = deal(plot_info.text1_pos(1),plot_info.text1_pos(2));

    x_d= x_frac * (x_lim(2) - x_lim(1));
    y_d= y_frac * (y_lim(2) - y_lim(1));                                 
    x_pos = x_lim(1) + x_d; 
    y_pos = y_lim(1) + y_d; 
    
    text(x_pos+y_d,y_pos+y_d*4,fit_eq,'FontSize',8,'Fontname','Times New Roman', 'Interpreter', 'tex');
    text(x_pos+y_d,y_pos+y_d*3,idx_n,'FontSize',8,'Fontname','Times New Roman', 'Interpreter', 'tex');
    text(x_pos+y_d,y_pos+y_d*2,idx_r2,'FontSize',8,'Fontname','Times New Roman', 'Interpreter', 'tex');%标记R
    text(x_pos,y_pos+y_d,idx_bias,'FontSize',8,'Fontname','Times New Roman', 'Interpreter', 'tex'); 
    text(x_pos,y_pos,idx_rmse,'FontSize',8,'Fontname','Times New Roman', 'Interpreter', 'tex');
    
    [x_frac2, y_frac2] = deal(plot_info.text2_pos(1),plot_info.text2_pos(2));
    x_d2= x_frac2 * (x_lim(2) - x_lim(1));
    y_d2= y_frac2 * (y_lim(2) - y_lim(1));                                 
    x_pos2 = x_lim(1) + x_d2; 
    y_pos2 = y_lim(1) + y_d2;
    text(x_pos2,y_pos2,plot_info.sitesID,...
        'FontSize',8,'Fontname','Times New Roman');
    
    set(gcf,'Color',[1,1,1]);%背景板设置为白色
    set(gca,'FontName','Times New Roman','FontSize',8);
    box on

    %% 绘制辅助信息及图像保存
    % 添加坐标轴标题
    % 构建带有单位的标题字符串
    xLabelStr = sprintf('%s (%s)', plot_info.xLabel, plot_info.units);
    yLabelStr = sprintf('%s (%s)', plot_info.yLabel, plot_info.units);
    % 设置坐标轴标签
    xlabel(xLabelStr, 'FontName', 'Times New Roman', 'FontSize', 8);
    ylabel(yLabelStr, 'FontName', 'Times New Roman', 'FontSize', 8);
    % title([num2str(date),' Scatter plot of ', xLabel, ' vs. ', yLabel]);
       
    % 检查表格中是否存在 'save' 列,并且其值为 0
    if ismember('save', plot_info.Properties.VariableNames) && plot_info.save == 0
        % 不保存图像
        disp('图像未保存')
    else
        imageName = [plot_info.imageName, '.tiff']; % 默认使用png格式
        fullPath = fullfile(plot_info.filePath, imageName);
        % 设置要保存的分辨率
        resolution = 300; % 例如,300 DPI   
        % 保存为指定分辨率的 JPEG 图像
        print(gcf, fullPath, '-dtiff', ['-r' num2str(resolution)]);
    end

    % 关闭图形窗口
    close(gcf);
end


注意:
以上散点密度图部分设置了3个可以实现的方法,可以任意选用看自己想用哪种效果,我用的是density2C.m函数,来自https://blog.csdn.net/slandarer/article/details/120242042?fromshare=blogdetail,很好用,感谢大佬的无私分享!

  1. 函数调用:
    以下为多个变量的批量出图
    % 提前设置好每个变量的参数,这里需要测试
    range_all={[0,800],[-100,300],[-100,300],[0,800],[0,800],[0,1200],[0,300]};%轴域范围
    text1_pos={[0.45,0.08], [0.45,0.08],[0.45,0.08], [0.45,0.08],...
       [0.45,0.08], [0.45,0.08],[0.45,0.08]};%text1的定位
    text2_pos={[0.08,0.9], [0.08,0.9],[0.08,0.9], [0.08,0.9],...
       [0.08,0.9], [0.08,0.9],[0.08,0.9]};%text2的定位
       
    ax_d=[200,100,100,200,200,300,100];%轴间距信息
      
    plot_vars= fieldnames(flux_vars);
    check_flux.(plot_vars{1})= flxdat.AAAA; 
    check_flux.(plot_vars{2})= flxdat.BBBB; 
    check_flux.(plot_vars{3})= flxdat.CCCC; 
    check_flux.(plot_vars{4})= flxdat.DDDD; 
    check_flux.(plot_vars{5})= flxdat.EEEE; 
    check_flux.(plot_vars{6})= flxdat.FFFF; 
    check_flux.(plot_vars{7})= flxdat.GGGG; 

    for j=1:length(plot_vars)
        x_obs=check_flux.(plot_vars{j});
        y_sim=flux_vars.(plot_vars{j});
        [check_vars,valid_vars]= calculate_metrics(plot_vars{j},x_obs,y_sim);%与观测数据对比

        % 绘制散点图
        plot_info=table;
        plot_info.size=[8,6];
        plot_info.range=range_all{j};%先粗出图设置为[],测试好再确定统一范围
        plot_info.ax_d=ax_d(j);%纵轴间距
        plot_info.text1_pos=text1_pos{j};%[x_frac, y_frac]
        plot_info.text2_pos=text2_pos{j};%[x_frac, y_frac]

        plot_info.xLabel=strcat(plot_vars{j},'_o_b_s');
        plot_info.yLabel=strcat(plot_vars{j},'_m_o_d');
        plot_info.units='W/m^2';
        plot_info.sitesID=sites(i);
        plot_info.filePath=fullfile(wdir,'\data\data_check\4_AA_check\');
        plot_info.imageName=strcat(sites{i},'_scatter_',plot_vars{j});
    %     plot_info.save=0;%0代表不保存,1代表保存,如果不设置这个,默认保存
    
        coeff=plot_scatter(x_obs,y_sim,1,check_vars,plot_info);
        check_vars.slope=coeff(1);
        check_vars.intercept=coeff(2);
        end

4.定位逻辑:
在这里插入图片描述
5.批量问题:
以上还只是1张1张批量出,不是subplot版本,我自己画的subplot版本还不够成熟好看,待继续摸索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值