29 views (last 30 days)
Show older comments
Andy on 23 May 2024 at 19:29
-
-
Link
Direct link to this question
https://in.mathworks.com/matlabcentral/answers/2122021-quiver-plot-of-coordinate-error-with-wrong-arrow-lengths
Commented: Voss on 24 May 2024 at 17:08
- DSC03765.xlsx
Open in MATLAB Online
I'm working on a quiver plot that represents coordinate error in images.
However, the magnitude of the vectors is not being represented correctly: for example, some small erros are being draw as bigger lines.
The magnitudes seems to be calculated correctly, but 'idx' is always 0 or 1, although there are 4 magnitude classes; also, the lengths of arrows are wrong in the figures.
I'm plotting 5 figures, but magnitude thresholds are calculated considering the set of images to generate a common legend.
% data
x1 = xlsread('DSC03765.xlsx',1,'A14:A614');
y1 = xlsread('DSC03765.xlsx',1,'B14:B614');
errorx1 = xlsread('DSC03765.xlsx',1,'E14:E614');
errory1 = xlsread('DSC03765.xlsx',1,'F14:F614');
x2 = xlsread('DSC03765.xlsx',2,'A14:A614');
y2 = xlsread('DSC03765.xlsx',2,'B14:B614');
errorx2 = xlsread('DSC03765.xlsx',2,'E14:E614');
errory2 = xlsread('DSC03765.xlsx',2,'F14:F614');
x3 = xlsread('DSC03765.xlsx',3,'A14:A614');
y3 = xlsread('DSC03765.xlsx',3,'B14:B614');
errorx3 = xlsread('DSC03765.xlsx',3,'E14:E614');
errory3 = xlsread('DSC03765.xlsx',3,'F14:F614');
x4 = xlsread('DSC03765.xlsx',4,'A14:A614');
y4 = xlsread('DSC03765.xlsx',4,'B14:B614');
errorx4 = xlsread('DSC03765.xlsx',4,'E14:E614');
errory4 = xlsread('DSC03765.xlsx',4,'F14:F614');
x5 = xlsread('DSC03765.xlsx',5,'A14:A614');
y5 = xlsread('DSC03765.xlsx',5,'B14:B614');
errorx5 = xlsread('DSC03765.xlsx',5,'E14:E614');
errory5 = xlsread('DSC03765.xlsx',5,'F14:F614');
% calculate magnitude
magnitude1 = sqrt(errorx1.^2+errory1.^2);
magnitude2 = sqrt(errorx2.^2+errory2.^2);
magnitude3 = sqrt(errorx3.^2+errory3.^2);
magnitude4 = sqrt(errorx4.^2+errory4.^2);
magnitude5 = sqrt(errorx5.^2+errory5.^2);
magnitude_total = [];
magnitudes = {magnitude1, magnitude2, magnitude3, magnitude4, magnitude5};
% concatenate values of magnitude in one array
for i = 1:length(magnitudes)
magnitude_total = vertcat(magnitude_total, magnitudes{i});
end
% calculate min and max magnitude
mag_res = 0.05;
magnitudelim = [ ...
floor(min(magnitude_total)/mag_res) ...
ceil(max(magnitude_total)/mag_res) ...
]*mag_res;
% define a color map
n_colors = 4;
cmap = jet(n_colors);
% calculate the magnitude thresholds
mthresholds = linspace(magnitudelim(1),magnitudelim(2),n_colors+1);
% plot function
function plot_image(x, y, errorx, errory, magnitude, mthresholds, cmap, magnitudelim, n_colors, img_title)
figure
hold on
% for each color, find the indicies of the magnitudes at this color level
for ii = 1:n_colors
idx = magnitude >= mthresholds(ii) & magnitude < mthresholds(ii+1);
% generate an arrow of the corresponding color
quiver(x(idx), y(idx), errorx(idx), errory(idx), 0.5, 'Color', cmap(ii,:));
end
% set up the colorbar
colormap(cmap);
colorbar();
caxis(magnitudelim);
xlim([0 2836])
ylim([0 2778])
title(img_title);
hold off
end
% plot all figures
plot_image(x1, y1, errorx1, errory1, magnitude1, mthresholds, cmap, magnitudelim, n_colors, '570nm');
plot_image(x2, y2, errorx2, errory2, magnitude2, mthresholds, cmap, magnitudelim, n_colors, '525nm');
plot_image(x3, y3, errorx3, errory3, magnitude3, mthresholds, cmap, magnitudelim, n_colors, '850nm');
plot_image(x4, y4, errorx4, errory4, magnitude4, mthresholds, cmap, magnitudelim, n_colors, '490nm');
plot_image(x5, y5, errorx5, errory5, magnitude5, mthresholds, cmap, magnitudelim, n_colors, '550nm');
1 Comment Show -1 older commentsHide -1 older comments
Show -1 older commentsHide -1 older comments
Voss on 24 May 2024 at 15:36
Direct link to this comment
https://in.mathworks.com/matlabcentral/answers/2122021-quiver-plot-of-coordinate-error-with-wrong-arrow-lengths#comment_3171091
Open in MATLAB Online
- DSC03765.xlsx
By the way, here is a more succinct version, which uses readtable instead of xlsread (which is no longer recommended) and uses arrays (cell arrays, tables) instead of sequences of numbered variables (x1, x2, x3, ...):
sheet_names = sheetnames('DSC03765.xlsx');
N = numel(sheet_names);
C = cell(1,N);
for ii = 1:N
% read sheet
T = readtable('DSC03765.xlsx','Sheet',ii);
% rename table variables
T = renamevars(T,1:width(T),{'x','y','foo','bar','errorx','errory'});
% calculate magnitude
T.magnitude = sqrt(T.errorx.^2+T.errory.^2);
% store table in cell array
C{ii} = T;
end
% concatenate values of magnitude in one array
magnitude_total = vertcat(C{:}).magnitude;
% calculate min and max magnitude
mag_res = 0.05;
magnitudelim = [ ...
floor(min(magnitude_total)/mag_res) ...
ceil(max(magnitude_total)/mag_res) ...
]*mag_res;
% define a color map
n_colors = 4;
cmap = jet(n_colors);
% calculate the magnitude thresholds
mthresholds = linspace(magnitudelim(1),magnitudelim(2),n_colors+1);
nm = [570 525 850 490 550];
common_scale_factor = 50;
for ii = 1:numel(C)
plot_image(C{ii}.x, C{ii}.y, common_scale_factor*C{ii}.errorx, common_scale_factor*C{ii}.errory, ...
C{ii}.magnitude, mthresholds, cmap, magnitudelim, n_colors, nm(ii));
end
% plot function
function plot_image(x, y, errorx, errory, magnitude, mthresholds, cmap, magnitudelim, n_colors, nm)
figure
hold on
% for each color, find the indicies of the magnitudes at this color level
for ii = 1:n_colors
idx = magnitude >= mthresholds(ii) & magnitude < mthresholds(ii+1);
% generate an arrow of the corresponding color
quiver(x(idx), y(idx), errorx(idx), errory(idx), 'off', 'Color', cmap(ii,:));
end
% set up the colorbar
colormap(cmap);
colorbar();
caxis(magnitudelim);
xlim([0 2836])
ylim([0 2778])
title(sprintf('%d nm',nm));
hold off
end
Sign in to comment.
Sign in to answer this question.
Answers (1)
Voss on 24 May 2024 at 15:11
Edited: Voss on 24 May 2024 at 15:12
Open in MATLAB Online
- DSC03765.xlsx
"some small erros are being draw as bigger lines"
That's because each quiver plot scales its own arrows' lengths independently of any other quiver plots.
Using a scale factor of 0.5 means each quiver plot's arrows are half as long as they would be if they were automatically scaled not to overlap, as described in the documentation,
- When scale is a positive number, the quiver function automatically adjusts the lengths of arrows so they do not overlap, then stretches them by a factor of scale. For example, a scale of 2 doubles the length of arrows, and a scale of 0.5 halves the length of arrows.
But this implies nothing about the relative length of one quiver plot's arrows compared to another quiver plot's arrows. Since each quiver plot's arrow lengths are scaled independently, it's impossible to enforce any relationship between multiple quiver plots' arrow lengths when using automatic scaling.
However, you can turn automatic scaling off, and manually apply a scale factor to the arrow magnitudes (i.e., multiply the U and V by some factor before sending them to quiver). Using the same factor for all quiver plots will scale them all together. See the variable common_scale_factor below, and adjust it until the plots look like what you want.
% data
x1 = xlsread('DSC03765.xlsx',1,'A14:A614');
y1 = xlsread('DSC03765.xlsx',1,'B14:B614');
errorx1 = xlsread('DSC03765.xlsx',1,'E14:E614');
errory1 = xlsread('DSC03765.xlsx',1,'F14:F614');
x2 = xlsread('DSC03765.xlsx',2,'A14:A614');
y2 = xlsread('DSC03765.xlsx',2,'B14:B614');
errorx2 = xlsread('DSC03765.xlsx',2,'E14:E614');
errory2 = xlsread('DSC03765.xlsx',2,'F14:F614');
x3 = xlsread('DSC03765.xlsx',3,'A14:A614');
y3 = xlsread('DSC03765.xlsx',3,'B14:B614');
errorx3 = xlsread('DSC03765.xlsx',3,'E14:E614');
errory3 = xlsread('DSC03765.xlsx',3,'F14:F614');
x4 = xlsread('DSC03765.xlsx',4,'A14:A614');
y4 = xlsread('DSC03765.xlsx',4,'B14:B614');
errorx4 = xlsread('DSC03765.xlsx',4,'E14:E614');
errory4 = xlsread('DSC03765.xlsx',4,'F14:F614');
x5 = xlsread('DSC03765.xlsx',5,'A14:A614');
y5 = xlsread('DSC03765.xlsx',5,'B14:B614');
errorx5 = xlsread('DSC03765.xlsx',5,'E14:E614');
errory5 = xlsread('DSC03765.xlsx',5,'F14:F614');
% calculate magnitude
magnitude1 = sqrt(errorx1.^2+errory1.^2);
magnitude2 = sqrt(errorx2.^2+errory2.^2);
magnitude3 = sqrt(errorx3.^2+errory3.^2);
magnitude4 = sqrt(errorx4.^2+errory4.^2);
magnitude5 = sqrt(errorx5.^2+errory5.^2);
magnitude_total = [];
magnitudes = {magnitude1, magnitude2, magnitude3, magnitude4, magnitude5};
% concatenate values of magnitude in one array
for i = 1:length(magnitudes)
magnitude_total = vertcat(magnitude_total, magnitudes{i});
end
% calculate min and max magnitude
mag_res = 0.05;
magnitudelim = [ ...
floor(min(magnitude_total)/mag_res) ...
ceil(max(magnitude_total)/mag_res) ...
]*mag_res;
% define a color map
n_colors = 4;
cmap = jet(n_colors);
% calculate the magnitude thresholds
mthresholds = linspace(magnitudelim(1),magnitudelim(2),n_colors+1);
% plot function
function plot_image(x, y, errorx, errory, magnitude, mthresholds, cmap, magnitudelim, n_colors, img_title)
figure
hold on
common_scale_factor = 50;
% for each color, find the indicies of the magnitudes at this color level
for ii = 1:n_colors
idx = magnitude >= mthresholds(ii) & magnitude < mthresholds(ii+1);
% generate an arrow of the corresponding color
quiver(x(idx), y(idx), common_scale_factor*errorx(idx), common_scale_factor*errory(idx), 'off', 'Color', cmap(ii,:));
end
% set up the colorbar
colormap(cmap);
colorbar();
caxis(magnitudelim);
xlim([0 2836])
ylim([0 2778])
title(img_title);
hold off
end
% plot all figures
plot_image(x1, y1, errorx1, errory1, magnitude1, mthresholds, cmap, magnitudelim, n_colors, '570nm');
plot_image(x2, y2, errorx2, errory2, magnitude2, mthresholds, cmap, magnitudelim, n_colors, '525nm');
plot_image(x3, y3, errorx3, errory3, magnitude3, mthresholds, cmap, magnitudelim, n_colors, '850nm');
plot_image(x4, y4, errorx4, errory4, magnitude4, mthresholds, cmap, magnitudelim, n_colors, '490nm');
plot_image(x5, y5, errorx5, errory5, magnitude5, mthresholds, cmap, magnitudelim, n_colors, '550nm');
(For the other question, "'idx' is always 0 or 1" because idx is a logical vector, which is used for (logical) indexing.)
2 Comments Show NoneHide None
Show NoneHide None
Andy on 24 May 2024 at 16:58
Direct link to this comment
https://in.mathworks.com/matlabcentral/answers/2122021-quiver-plot-of-coordinate-error-with-wrong-arrow-lengths#comment_3171191
Oh, I see now.
I thought there was proportionality between each other lengths.
This was very helpful, I really appreciate it. Thanks!
Voss on 24 May 2024 at 17:08
Direct link to this comment
https://in.mathworks.com/matlabcentral/answers/2122021-quiver-plot-of-coordinate-error-with-wrong-arrow-lengths#comment_3171216
You're welcome! Any questions, let me know. Otherwise, please "Accept" this answer. Thanks!
Sign in to comment.
Sign in to answer this question.
See Also
Categories
MATLABGraphics2-D and 3-D PlotsVector Fields
Find more on Vector Fields in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- Deutsch
- English
- Français
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)
Contact your local office