How to generate a map of European countries coloured according to a vector of positive and negative values?
조회 수: 38 (최근 30일)
이전 댓글 표시
Hello all,
I am trying to get a map of the European countries (cou_nam) in which the color of each country is assigned according to a vector including 0, positive and negative values (data).
The approach I follow is based on both the Mapping Toolbox as well as the borders file exchange submission.
% country names
cou_nam = {'Belgium', 'Bulgaria', 'Czech Republic', 'Denmark', 'Germany','Estonia','Ireland',...
'Greece','Spain','France','Croatia','Italy', 'Cyprus','Latvia', 'Lithuania', 'Luxembourg',...
'Hungary', 'Malta', 'Netherlands','Austria', 'Poland', 'Portugal','Romania','Slovenia', 'Slovakia',...
'Finland', 'Sweden'};
numRegions = length(cou_nam);
cmap = colormap;
% Random vector of values (one for each country)
data = randi([-5,5],numRegions,1);
% Map
figure('Color','w')
xh = worldmap('Europe');
setm(xh,'MapProjection','miller')
tightmap
geoshow ('landareas.shp', 'FaceColor', 'white');
for i = 1:1:numRegions
bordersm(cou_nam{i},'facecolor',cmap(data(i),:)) % => problem with negative values
end
colorbar
The issue with this code is that the variable data stores both negative and positive values, so when called in the for loop gets back an error since only positive integers are accepted.
Also, if I insert only positive values, i.e.
data = randi([1,5],numRegions,1);
it seems that the colorbar doesn't conform with the range of the values in data.
I have seen that there are similar questions (here and here) in the Community, yet I have not managed to get a solution.
Thanks!
댓글 수: 0
채택된 답변
DGM
2022년 4월 26일
편집: DGM
2022년 4월 26일
This should work. Note that the placeholder data isn't even integer-valued.
% country names
cou_nam = {'Belgium', 'Bulgaria', 'Czech Republic', 'Denmark', 'Germany','Estonia','Ireland',...
'Greece','Spain','France','Croatia','Italy', 'Cyprus','Latvia', 'Lithuania', 'Luxembourg',...
'Hungary', 'Malta', 'Netherlands','Austria', 'Poland', 'Portugal','Romania','Slovenia', 'Slovakia',...
'Finland', 'Sweden'};
numRegions = length(cou_nam);
cmap = jet(256); % specify the colormap
% Random vector of values (one for each country)
datarange = [-5 5]; % get the actual range of the data
data = range(datarange)*rand(numRegions,1) + min(datarange); % i'm assuming this is a placeholder
coloridx = round(rescale(data,1,size(cmap,1))); % rescale the data to use as an index into cmap
% Map
figure('Color','w')
xh = worldmap('Europe');
setm(xh,'MapProjection','miller')
tightmap
geoshow ('landareas.shp', 'FaceColor', 'white');
for i = 1:1:numRegions
bordersm(cou_nam{i},'facecolor',cmap(coloridx(i),:))
end
colorbar
colormap(cmap) % specify the colormap
caxis(datarange) % set caxis to match datarange
댓글 수: 3
DGM
2022년 4월 26일
If your data is relatively centered about 0, then you can do that by just using a colormap that's gray in the middle.
% country names
cou_nam = {'Belgium', 'Bulgaria', 'Czech Republic', 'Denmark', 'Germany','Estonia','Ireland',...
'Greece','Spain','France','Croatia','Italy', 'Cyprus','Latvia', 'Lithuania', 'Luxembourg',...
'Hungary', 'Malta', 'Netherlands','Austria', 'Poland', 'Portugal','Romania','Slovenia', 'Slovakia',...
'Finland', 'Sweden'};
numRegions = length(cou_nam);
cmap = jet(31); % specify the colormap (with an odd length
cmap(ceil(size(cmap,1)/2),:) = [192 192 192]/255;
% Random vector of values (one for each country)
data = 10*rand(numRegions,1) - 5; % i'm assuming this is a placeholder
datarange = [-5 5]; % nominal data range needs to be symmetric
% rescale the data to use as an index into cmap
coloridx = round((data-min(datarange))/range(datarange) * (size(cmap,1)-1) + 1);
% Map
%figure('Color','w')
xh = worldmap('Europe');
setm(xh,'MapProjection','miller')
tightmap
geoshow('landareas.shp', 'FaceColor', 'white');
for i = 1:1:numRegions
bordersm(cou_nam{i},'facecolor',cmap(coloridx(i),:))
end
colorbar
colormap(cmap) % specify the colormap
caxis(datarange) % needs to match datarange
You will need to make sure that clim() uses the values from nominal range specified by datarange and not the actual extrema of the data. Remember that you're explicitly coloring objects instead of letting the axes apply a scaled colormap. You're basically doing the colormapping yourself, so the colorbar will need to correspond to it, otherwise the colorbar won't reflect the values they're supposed to.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 White에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!