当前位置: 首页 > news >正文

MATLAB | 绘图复刻(十三) | 带NaN图例的地图绘制

有粉丝问我地图绘制如何添加NaN,大概像这样:

或者这样:

直接上干货:


原始绘图

假设我们有这样的一张图地图,注意运行本文代码需要去matlab官网下载Mapping Toolbox工具箱,但是其实原理都是相似的,如果M_map工具箱绘图也是类似的修改方法。

此外此处用到的nclCM函数如何获取请看这篇文章:https://slandarer.blog.csdn.net/article/details/127935365

或者去文末gitee仓库获取也行。

% 需要mapping toolbox
[Z,R]=readgeoraster('n39_w106_3arc_v2.dt1','OutputType','double');key.GTModelTypeGeoKey=2;
key.GTRasterTypeGeoKey=2;
key.GeographicTypeGeoKey=4326;filename='southboulder.tif';
geotiffwrite(filename,Z,R,'GeoKeyDirectoryTag',key)usamap([39 40],[-106 -105])
g=geoshow(filename,'DisplayType','mesh');% 190 300 363
colormap(nclCM(15,100))
cbHdl=colorbar();


1 方法一

1.1 添加NaN

对于这个工具箱的这种绘图方式,比如我们想将数值低于2100的数值改成NaN,首先将原始代码改成这样:

% 需要mapping toolbox
[Z,R]=readgeoraster('n39_w106_3arc_v2.dt1','OutputType','double');key.GTModelTypeGeoKey=2;
key.GTRasterTypeGeoKey=2;
key.GeographicTypeGeoKey=4326;filename='southboulder.tif';
% 设置NaN值
Z(Z<2100)=nan;
geotiffwrite(filename,Z,R,'GeoKeyDirectoryTag',key)usamap([39 40],[-106 -105])
g=geoshow(filename,'DisplayType','mesh');% 190 300 363
colormap(nclCM(15,100))
cbHdl=colorbar();

1.2 生成NaN图例

在绘图区域外绘制个小方块并生成图例:

% 绘制nan图例
nanHdl=fill([0,1,1,0]-1000,[0,0,1,1]-1000,[240,240,240]./255,...'EdgeColor','none','EdgeColor',[160,160,160]./255,'LineWidth',1.2,...'DisplayName',' NaN');
lgdHdl=legend(nanHdl);

1.3 修改图例位置

将上一步的代码改成这样(可能大家绘图比例不同需要根据实际情况微调):

% 修改colorbar位置
tPosition=cbHdl.Position;
cbHdl.Position(1)=cbHdl.Position(1)+tPosition(3).*1.5;
cbHdl.Position(2)=cbHdl.Position(2)+tPosition(4)./10;
cbHdl.Position(4)=cbHdl.Position(4)-tPosition(4)./10;% 绘制nan图例
nanHdl=fill([0,1,1,0]-1000,[0,0,1,1]-1000,[240,240,240]./255,...'EdgeColor','none','EdgeColor',[160,160,160]./255,'LineWidth',1.2,...'DisplayName',' NaN');
lgdHdl=legend(nanHdl);
lgdHdl.Box='off';
lgdHdl.ItemTokenSize=[16,16];
lgdHdl.Position(1)=tPosition(1)+tPosition(3).*1.3;
lgdHdl.Position(2)=tPosition(2);

1.4 方法一完整代码

% 需要mapping toolbox
[Z,R]=readgeoraster('n39_w106_3arc_v2.dt1','OutputType','double');key.GTModelTypeGeoKey=2;
key.GTRasterTypeGeoKey=2;
key.GeographicTypeGeoKey=4326;filename='southboulder.tif';
% 设置NaN值
Z(Z<2100)=nan;
geotiffwrite(filename,Z,R,'GeoKeyDirectoryTag',key)usamap([39 40],[-106 -105])
g=geoshow(filename,'DisplayType','mesh');% 190 300 363
colormap(nclCM(15,100))
cbHdl=colorbar();
% 修改colorbar位置
tPosition=cbHdl.Position;
cbHdl.Position(1)=cbHdl.Position(1)+tPosition(3).*1.5;
cbHdl.Position(2)=cbHdl.Position(2)+tPosition(4)./10;
cbHdl.Position(4)=cbHdl.Position(4)-tPosition(4)./10;% 绘制nan图例
nanHdl=fill([0,1,1,0]-1000,[0,0,1,1]-1000,[240,240,240]./255,...'EdgeColor','none','EdgeColor',[160,160,160]./255,'LineWidth',1.2,...'DisplayName',' NaN');
lgdHdl=legend(nanHdl);
lgdHdl.Box='off';
lgdHdl.ItemTokenSize=[16,16];
lgdHdl.Position(1)=tPosition(1)+tPosition(3).*1.3;
lgdHdl.Position(2)=tPosition(2);

2 方法二

2.1 重设范围

这里假设NaN值被存为了-999,我们将将NaN部分数值设置为非NaN值最小值-1/10的非NaN值数值范围,这样colorbar灰色部分的长度就会是不是灰色的部分长度的1/10。

% 需要mapping toolbox
[Z,R]=readgeoraster('n39_w106_3arc_v2.dt1','OutputType','double');key.GTModelTypeGeoKey=2;
key.GTRasterTypeGeoKey=2;
key.GeographicTypeGeoKey=4326;filename='southboulder.tif';
% 假设NaN值被存为-999
Z(Z<2100)=-999;% 将其数值设置为非NaN值最小值-1/10的非NaN值数值范围
% 这样colorbar灰色部分的长度就会是不是灰色的部分长度的1/10;
Z(Z==-999)=nan;minVal=min(min(Z));
Z(isnan(Z))=min(min(Z))-(max(max(Z))-min(min(Z)))./10;
geotiffwrite(filename,Z,R,'GeoKeyDirectoryTag',key)usamap([39 40],[-106 -105])
g=geoshow(filename,'DisplayType','mesh');

2.2 修改配色

往colormap前面续加上一段等长的灰色:

CList=nclCM(15,100);
CList=[(CList(:,1).*0+1)*[240,240,240]./255;CList];
colormap(CList)
cbHdl=colorbar();

2.3 中心移动到NaN与数值交界处

使用我自己写的setPivot函数:

function setPivot(varargin)
% @author:slandarer
if nargin==0ax=gca;pivot=0;
elseif isa(varargin{1},'matlab.graphics.axis.Axes')ax=varargin{1};if nargin>1pivot=varargin{2};elsepivot=0;endelseax=gca;pivot=varargin{1};end
end
tryCLimit=get(ax,'CLim');
catch
end
tryCLimit=get(ax,'ColorLimits');
catch
end
% CMap=get(ax,'Colormap');
CMap=colormap(ax);CLen=[pivot-CLimit(1),CLimit(2)-pivot];
if all(CLen>0)[CV,CInd]=sort(CLen);CRatio=round(CV(1)/CV(2).*300)./300;CRatioCell=split(rats(CRatio),'/');if length(CRatioCell)>1Ratio=[str2double(CRatioCell{1}),str2double(CRatioCell{2})];Ratio=Ratio(CInd);N=size(CMap,1);CList1=CMap(1:floor(N/2),:);CList2=CMap((floor(N/2)+1):end,:);if mod(N,2)~=0CList3=CList2(1,:);CList2(1,:)=[];CInd1=kron((1:size(CList1,1))',ones(Ratio(1)*2,1));CInd2=kron((1:size(CList2,1))',ones(Ratio(2)*2,1));CMap=[CList1(CInd1,:);repmat(CList3,[Ratio(1)+Ratio(2),1]);CList2(CInd2,:)];elseCInd1=kron((1:size(CList1,1))',ones(Ratio(1),1));CInd2=kron((1:size(CList2,1))',ones(Ratio(2),1));CMap=[CList1(CInd1,:);CList2(CInd2,:)];end% set(ax,'Colormap',CMap)colormap(ax,CMap);end
end
end

中心移动到NaN与数值交界处:

% 调整配色范围
setPivot(minVal)

2.4 修改图例标签

% 调整colorbar标签文字
cbHdl.TickLabels{cbHdl.Ticks<minVal}='';
cbHdl.TickLabels{1}='NaN';

2.5 方法二完整代码

% 需要mapping toolbox
[Z,R]=readgeoraster('n39_w106_3arc_v2.dt1','OutputType','double');key.GTModelTypeGeoKey=2;
key.GTRasterTypeGeoKey=2;
key.GeographicTypeGeoKey=4326;filename='southboulder.tif';
% 假设NaN值被存为-999
Z(Z<2100)=-999;% 将其数值设置为非NaN值最小值-1/10的非NaN值数值范围
% 这样colorbar灰色部分的长度就会是不是灰色的部分长度的1/10;
Z(Z==-999)=nan;minVal=min(min(Z));
Z(isnan(Z))=min(min(Z))-(max(max(Z))-min(min(Z)))./10;
geotiffwrite(filename,Z,R,'GeoKeyDirectoryTag',key)usamap([39 40],[-106 -105])
g=geoshow(filename,'DisplayType','mesh');% 往colormap前面续加上一段等长的灰色
CList=nclCM(15,100);
CList=[(CList(:,1).*0+1)*[240,240,240]./255;CList];
colormap(CList)
cbHdl=colorbar();% 调整配色范围
setPivot(minVal)% 调整colorbar标签文字
cbHdl.TickLabels{cbHdl.Ticks<minVal}='';
cbHdl.TickLabels{1}='NaN';

以上已经是完整代码,懒得一一搜集文件可以从以下Gitee仓库获取,setPivot函数和nclCM工具包我也一块扔文件夹啦:

  • https://gitee.com/slandarer/PLTreprint/

相关文章:

  • Pytorch从零开始实战10
  • Doris中的物化视图(十八)
  • DNS协议、ICMP协议、NAT技术
  • fastdfs-client-java-1.30 maven 打包安装
  • 计算机网络_第五章_运输层
  • 红酒按照糖含量怎么分类?
  • 渲染农场渲染一分钟动画需要多少钱?需要渲染多少时间?
  • 贪心算法个人见解
  • java.math.BigDecimal cannot be cast to java.lang.String问题
  • Linux的基本指令 ( 一 )
  • 服务器环境是什么意思?
  • Elasticsearch:ES|QL 函数及操作符
  • 18.天气小案例
  • 华为---OSPF网络虚连接(Virtual Link)简介及示例配置
  • curl添加https服务
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • C# 免费离线人脸识别 2.0 Demo
  • CentOS从零开始部署Nodejs项目
  • Django 博客开发教程 8 - 博客文章详情页
  • Java应用性能调优
  • KMP算法及优化
  • underscore源码剖析之整体架构
  • vue脚手架vue-cli
  • Webpack 4 学习01(基础配置)
  • 二维平面内的碰撞检测【一】
  • 简单数学运算程序(不定期更新)
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 开发基于以太坊智能合约的DApp
  • 深度学习在携程攻略社区的应用
  • 使用API自动生成工具优化前端工作流
  • 我看到的前端
  • 新书推荐|Windows黑客编程技术详解
  • Linux权限管理(week1_day5)--技术流ken
  • ​io --- 处理流的核心工具​
  • !!java web学习笔记(一到五)
  • # C++之functional库用法整理
  • #Linux(Source Insight安装及工程建立)
  • #NOIP 2014#Day.2 T3 解方程
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (1)Nginx简介和安装教程
  • (14)Hive调优——合并小文件
  • (6)添加vue-cookie
  • (第一天)包装对象、作用域、创建对象
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)ssm码农论坛 毕业设计 231126
  • (六)Hibernate的二级缓存
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .cfg\.dat\.mak(持续补充)
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .net 发送邮件
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值