【问题标题】:MATLAB Avoid text overlap in a mapMATLAB 避免地图中的文本重叠
【发布时间】:2013-10-11 20:36:20
【问题描述】:

我有一张用标签绘制点的地图。现在,在标签靠得很近的地方,标签会重叠。我看到有人建议使用 textbp (FileExchange),但我从单元格数组中的列中获取标签,因此该函数不起作用。我怎样才能使标签放置在离点足够远的地方,以便清楚地看到所有标签?如果不清楚哪个标签代表哪个情节,也许可以添加箭头?

数据是这个文件:https://www.dropbox.com/sh/li3hh1nvt11vok5/4YGfwStQlo。 我从这个文件中提取数据并对其进行排序,找到唯一值,然后用它来绘制点。

这是我脚本的地图部分:

%% Use function to read in 2012
    % Format: data = ('filename', 'delimiter')
filename = ('PM2.5_NY_2012.csv'); % PM2.5 88101 and 88502 data from NY 

data = read_mixed_csv(filename,', '); % 2012 must have ',' taken out first. DO NOT need to use for 2011 
data = read_mixed_csv(filename,'"'); % Creates cell array of data (2011, 2012)
data = regexprep(data, '^"|"$',''); % Gets rid of double quotes at the start and end of the string 
data = data(:,2:2:end); % 2012. Do it only if there are blank columns. Keep only the even cells because the odd ones are just commas
PM25_NY_2012 = data;

%% Pull data of a specific parameter (Latitude and Longitude - Columns 20 and 21)

% Pull out data with Local Conditions only (Locations differ compared to Acceptable PM2.5
data_Loc = data(strcmp('PM2.5 - Local Conditions', data(:,10)),:);

% Pull out data with Acceptable PM2.5 AQI only
data_Acc = data(strcmp('Acceptable PM2.5 AQI & Speciation Mass', data(:,10)),:); 

%% Find index for the first unique lat and lon
% Local Conditions
[C,ia,ic] = unique(data_Loc(:,2));
DupIndex = setdiff(1:size(data_Loc(:,2)), ia);
data_Loc(DupIndex,:) = [];

datalat_Loc = data_Loc(:,19);
datalon_Loc = data_Loc(:,20);

% Acceptable PM2.5
[C, ia,ic] = unique(data_Acc(:,2));
DupIndex = setdiff(1:size(data_Acc(:,2)), ia);
data_Acc(DupIndex,:) = [];

datalat_Acc = data_Acc(:,19);
datalon_Acc = data_Acc(:,20);

%% Plot map
latlim = [39 47];
lonlim = [-81 -70];
figure('Color','w');

% Plot for Acceptable PM2.5
subplot(1,2,1)

usamap('New York'); % 'Vermont', 'Massachusetts', 'Rhode Island', 'Connecticut', 'New Jersey', 'Pennsylvania', 'Delaware', 'Maryland')
shi = shaperead('usastatehi', 'UseGeoCoords', true,...
            'Selector',{@(name) strcmpi(name,'New York'), 'Name'});
geoshow(shi, 'FaceColor', [0.3 1.0, 0.675])
textm(shi.LabelLat, shi.LabelLon, shi.Name, 'HorizontalAlignment', 'center')

[row,col] = size(datalat_Acc);
nb_point = row;
LAT = str2double(datalat_Acc);
LON = str2double(datalon_Acc);
h = geoshow(LAT, LON, 'DisplayType', 'Point', 'Marker', '*', 'Color', 'red');
textm(LAT, LON,(data_Acc(:,2))', 'FontSize',8)
title('PM2.5 Sites in New York State in 2012 - Acceptable PM2.5 AQI & Speciation Mass');

hold all

% Plot for Local Conditions
subplot(1,2,2)

% figure('Color','w');
usamap('New York'); % 'Vermont', 'Massachusetts', 'Rhode Island', 'Connecticut', 'New Jersey', 'Pennsylvania', 'Delaware', 'Maryland')
shi = shaperead('usastatehi', 'UseGeoCoords', true,...
            'Selector',{@(name) strcmpi(name,'New York'), 'Name'});
geoshow(shi, 'FaceColor', [0.3 1.0, 0.675])
textm(shi.LabelLat, shi.LabelLon, shi.Name, 'HorizontalAlignment', 'center')

[row,col] = size(datalat_Loc);
nb_point = row;
LAT = str2double(datalat_Loc);
LON = str2double(datalon_Loc);
h = geoshow(LAT, LON, 'DisplayType', 'Point', 'Marker', '+', 'Color', 'red');
textm(LAT, LON,(data_Loc(:,2))', 'FontSize',5)
title('PM2.5 Sites in New York State in 2012 - Local Conditions');

所以问题在于脚本的 textm 部分以重叠的方式绘制标签。

【问题讨论】:

    标签: matlab map plot overlap points


    【解决方案1】:

    您的代码没有按原样运行,没有 datalat_Acc 就挂断了。我不知道那是否在其中一个文件中。但是,您可以通过在制作文本标签时迭代并动态更改它们的位置来解决此问题。写出第一个标签,获取该标签的位置,并将第二个标签的位置设置为略低于它。然后你得到第二个标签的位置,并用它来调整第三个,依此类推。您还可以使用这些位置在标签和地图点之间画一条线。在这个例子中,我让它们都指向同一个地方,但是如果你根据你的代码调整它,你可以改变它。

    clf
    hold on
    plot(peaks)
    h=text(5,8,'label1', 'FontSize',8);
    posh=get(h,'position');
    
    for i=1:5
        h2=text(posh(1),posh(2)-0.5,['label',num2str(i+1)], 'FontSize',8);
        posh=get(h2,'position');
    
        plot([posh(1) 0],[posh(2) 7])
    end
    

    我确信有一种方法可以做到这一点,而无需遍历所有这些,但这是我想到的最容易编写的方法。

    【讨论】:

    • 我无法理解如何执行您的建议。一般来说,我对编码很陌生。我已经更新了上面的脚本以包含缺失的部分。它现在应该运行。你能看看吗?这将帮助我找出与我的特定案例更相关的东西。
    • 好吧,如果没有 read_mixed_csv(),它仍然无法运行。但是您仍然应该能够适应我的示例。 get(h,'position') 函数返回文本标签的数组 [x 坐标 y 坐标 z 坐标]。因此,您在 textm() 函数中使用 LAT 和 LON 值而不是 x 和 y。因此,首先您需要将 textm(LAT,LON...) 函数更改为 for 循环,然后您可以将 LAT 和 LON 替换为 position(1 & 2)。在循环中,每次放置 textm() 标签时,都可以使用 lat(i)=lat(i-1)-#degrees 的 lat 值,这会将标签向下移动到前一个标签下方#degrees。
    • 我会尝试这样做,并希望能够让它发挥作用。我已将 read_mixed_csv 添加到文件夹中。它是由某人将其作为 Stackoverflow 问题的答案发布的,所以我忘记了。
    • 嘿。我在我的脚本上尝试了代码,它看起来就像你的代码自己运行的一样。但它并没有指向每个点并告诉我标题是什么。相反,它给了我一列标签。你知道我做错了什么吗?我希望每个标签都被指向。目前,我不知道哪一点是哪个标签。谢谢。我在textm 之前的位置添加了以下内容。我现在只更改了第一个子图
    • h = textm(LAT(1,1), LON(1,1),(data_Acc(1,2))', 'FontSize', 8); posh = get(h, 'position'); for i = 1:length(data_Acc) h2 = text(posh(i), posh(i+1)-0.5, [(data_Acc(:,2))',num2str(i+1)], 'FontSize',8); posh=get(h2,'position'); plot([posh(1) 0],[posh(2) 7]) end 代码也已保存到文件夹中。
    猜你喜欢
    • 2011-05-22
    • 2023-03-21
    • 2019-12-21
    • 2015-03-22
    • 2021-08-10
    • 2011-12-11
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多