Reputation: 215
I am trying to produce 2D/3D quiver plots in MATLAB R2018b where the color of each vector corresponds to some scalar field over the same domain (e.g., the magnitude of each vector).
I am aware that this has been asked before and indeed received a great solution (which I have been using for a while now). However, it appears that R2018b included some changes to the undocumented LineStrip class and the solution no longer works. The arrows get removed from the plot and I just get the following warning message:
Warning: Error creating or updating LineStrip
Error in value of property ColorData
Array is wrong shape or size
Unfortunately, LineStrip being undocumented makes it rather difficult for me to figure out how to amend the earlier solution to make it work with the 2018b release. If anyone can help point me to the right direction, I would greatly appreciate it!
Upvotes: 1
Views: 1150
Reputation: 1
I also had this problem when trying to follow the same solution. I noticed that running the exact solution code worked fine but when working with my own code I would get the 'wrong shape' error you described. The issue turned out to be NaNs in my data - quiver does not add NaNs to the Head.VertexData so you need to remove any NaNs from your magnitude array before calling histcounts. Here I reproduce the error:
x = 1:5;
y = 1:5;
[X,Y] = meshgrid(x, y);
Z = zeros(size(X));
U = zeros(size(X));
V = (x-1).*(y-1)';
% add a single NaN to recreate the issue
V(3,3) = nan;
q = quiver(X, Y, U, V);
%// Compute the magnitude of the vectors
mag = hypot(U(:), V(:));
%// Get the current colormap
vec_cmap = colormap('hot');
%// Now determine the color to make each arrow using a colormap
clims = num2cell([0, max(mag, [], 'all','omitnan')]);
[~, ~, ind] = histcounts(mag, linspace(clims{:}, size(vec_cmap, 1)));
% [~, ~, ind] = histcounts(mag, size(vec_cmap, 1));
%// Now map this to a colormap to get RGB
cmap = uint8(ind2rgb(ind(:), vec_cmap) * 255);
cmap(:,:,4) = 255;
cmap = permute(repmat(cmap, [1 3 1]), [2 1 3]);
%// We repeat each color 3 times (using 1:3 below) because each arrow has 3 vertices
set(q.Head, ...
'ColorBinding', 'interpolated', ...
'ColorData', reshape(cmap(1:3,:,:), [], 4).'); %'
%// We repeat each color 2 times (using 1:2 below) because each tail has 2 vertices
set(q.Tail, ...
'ColorBinding', 'interpolated', ...
'ColorData', reshape(cmap(1:2,:,:), [], 4).');
Warning: Error creating or updating LineStrip Error in value of property ColorData Array is wrong shape or size
Warning: Error creating or updating LineStrip Error in value of property ColorData Array is wrong shape or size
And then a working version:
x = 1:5;
y = 1:5;
[X,Y] = meshgrid(x, y);
Z = zeros(size(X));
U = zeros(size(X));
V = (x-1).*(y-1)';
% add a single NaN to recreate the issue
V(3,3) = nan;
q = quiver(X, Y, U, V);
%// Compute the magnitude of the vectors
mag = hypot(U(:), V(:));
%// Get the current colormap
vec_cmap = colormap('hot');
%// Now determine the color to make each arrow using a colormap
clims = num2cell([0, max(mag, [], 'all','omitnan')]);
% Here is the solution - remove NaNs before binning
mag(isnan(mag)) = [];
[~, ~, ind] = histcounts(mag, linspace(clims{:}, size(vec_cmap, 1)));
% [~, ~, ind] = histcounts(mag, size(vec_cmap, 1));
%// Now map this to a colormap to get RGB
cmap = uint8(ind2rgb(ind(:), vec_cmap) * 255);
cmap(:,:,4) = 255;
cmap = permute(repmat(cmap, [1 3 1]), [2 1 3]);
%// We repeat each color 3 times (using 1:3 below) because each arrow has 3 vertices
set(q.Head, ...
'ColorBinding', 'interpolated', ...
'ColorData', reshape(cmap(1:3,:,:), [], 4).'); %'
%// We repeat each color 2 times (using 1:2 below) because each tail has 2 vertices
set(q.Tail, ...
'ColorBinding', 'interpolated', ...
'ColorData', reshape(cmap(1:2,:,:), [], 4).');
Upvotes: 0
Reputation: 1
I was running into the same error previously. I was using the same solution you cited, however this may not work for you since I am using Matlab 2017a.
I ran into the same issue as you and my problems arose from incorrectly calculating the magnitude of my vectors. Check out the dimensions of your mags vector and play with the section where that is calculated. That is what fixed it for me.
Apologies if this doesn't help!
Upvotes: 0