How to set a point to change color in colorbar

4 次查看(过去 30 天)
I want to use scatter3 with particles and want to have different color for positive and negative values of charge or velocities. I use this code through a Simulink prototype " Spiral Galaxy Formation Simulation "
oldPlot = scatter3(points_x,points_y,points_z,psize,points_col,'filled')
cmap = [1 0 0 ; 0 1 0 ] ; %2 color bar
colorbar;
colormap(cmap)
but when positive or negative gets higher values, then 0 is not the point that the color changes, but it moves towards the middle of the min and max value.
I want all positive to be green and all negative to be red.
I tried this code
cm=colormap;
cm(0,:)= [1 0 0];
colorbar;
colormap(cm)
but it doesn't seem to work.
  2 个评论
Rik
Rik 2018-1-1
Does it need to be one single scatter object? Otherwise you can simply plot the negative part separately from the positive part.
Christos Dimopoulos
I am not sure. I have tried that too, but it doesn't suit the project as you can see from the code...
for i = 1:n,
points_x(i) = bodies(i,2);
points_y(i) = bodies(i,3);
points_z(i) = bodies(i,4);
MassRange=(log10(abs(bodies(i,1)))-41.0)*500; % /SolarMass;
psize(i)=MassRange; % bodies(i,1)/(10e7*SolarMass);
points_col(i) = bodies(i,1)/SolarMass ; % MassRange
end
% Remove the old plot.
if isempty(oldPlot)
oldPlot = fig;
elseif ~isempty(foundFig)
cla
% delete(oldPlot);
end
oldPlot = scatter3(points_x,points_y,points_z,psize,points_col,'filled')
I think I need one plot because I compare particles, sizes, I have to make them interact between each other.

请先登录,再进行评论。

采纳的回答

Image Analyst
Image Analyst 2018-1-1
编辑:Image Analyst 2018-1-1
Try this:
% Initialization/clean up
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
fontSize = 13;
numPoints = 100;
points_x = rand(1,numPoints) - 0.5;
points_y = rand(1,numPoints) - 0.5;
points_z = rand(1,numPoints) - 0.5;
psize = 40;
% User wants "all positive to be green and all negative to be red."
% First default to all black;
points_col = zeros(numPoints, 3);
% Now find where ALL 3 coords are positive;
allPosIndexes = points_x > 0 & points_y > 0 & points_z > 0;
% Set those to green.
points_col(allPosIndexes, 2) = 1;
% Now find where ALL 3 coords are negative;
allNegIndexes = points_x < 0 & points_y < 0 & points_z < 0;
% Set those to red.
points_col(allNegIndexes, 1) = 1;
% Now one octant will be red, one octant will be green
% and 6 octants will be black.
% Now plot.
oldPlot = scatter3(points_x,points_y,points_z,psize,points_col,'filled')
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
zlabel('Z', 'FontSize', fontSize);
  4 个评论
Christos Dimopoulos
If I understood correctly, what I wrote was not helpful to you. I am attaching the whole program, so you will find functions and connections between them. I hope this helps.
Image Analyst
Image Analyst 2018-1-18
I've added Simulink to the Product list on the right hand side, so that others don't have to waste their time if they don't (like me) have Simulink. I'd say a minority of people here even have Simulink, so when people have a Simulink program, or any program that requires function available only in a certain toolbox or product they list that in the Products section. You might also attach the .mdl file to your original question up top.

请先登录,再进行评论。

更多回答(1 个)

Christos Dimopoulos
Thank you. I tried to "embed" your code in mine, but it doesn't seem to work. Can you see what's wrong please?
function PlotAll(bodies)
persistent fig;
persistent oldPlot;
coder.extrinsic('findobj','get','set','figure','clf','hold','text',...
'addfram','im2frame','delete','plot3','scatter3','psize',...
'colorbar','drawnow','getframe', 'VideoWriter', 'writeVideo',...
'open', 'M','num2str', 'cm');
n = size(bodies,1);
SpeedOfLight = 299792458; % in m/s
YearInSeconds = 365*24*60*60;
ShowStep = 20;
LightYear = SpeedOfLight*YearInSeconds;
Parsec = 3.26*LightYear;
SolarMass = 1.9891e+30;
foundFig = findobj('Tag','galaxyScreen');
if isempty(fig)||isempty(foundFig)
if isempty(foundFig)
fig = figure;
else
fig = figure(foundFig);
end;
clf(fig);
set(fig, 'Name', 'Simulation');
end
points_x = zeros(1,n);
points_y = zeros(1,n);
points_z = zeros(1,n);
points_mass = zeros(1,n);
psize = zeros(1,n);
% User wants "all positive to be green and all negative to be red."
% First default to all black;
points_col = zeros(n, 3);
for i = 1:n,
points_x(i) = bodies(i,2);
points_y(i) = bodies(i,3);
points_z(i) = bodies(i,4);
points_mass(i) = bodies(i,1);
MassRange=(log10(abs(bodies(i,1)))-41.0)*200; % /SolarMass;
if MassRange<=4,
MassRange=4;
end
psize(i)=MassRange; % bodies(i,1)/(10e7*SolarMass);
end
% Now find where ALL 3 coords are positive;
allPosIndexes = points_mass > 0 ;
% Set those to green.
points_col(allPosIndexes, 2) = 1;
% Now find where ALL 3 coords are negative;
allNegIndexes = points_mass < 0;
% Set those to red.
points_col(allNegIndexes, 1) = 1;
% Remove the old plot.
%
if isempty(oldPlot)
oldPlot = fig;
ShowStep=ShowStep+1;
elseif ~isempty(foundFig)
cla
ShowStep=ShowStep+1;
% delete(oldPlot);
end
oldPlot = scatter3(points_x,points_y,points_z,psize,points_col,'filled')
%colormap([repmat([0 1 0],-10e10,0); repmat([1 1 0],-10e10,0)]);
%cm=colormap;
%cm(0,:)= [1 1 1];
%cmap = [1 0 0 ; 0 1 0 ] ; %3 color bar
colorbar('color','w');
drawnow
It gives me error message...
Logical indexing requires support of variable-sized arrays, which is currently disabled.
Function 'Plot all bodies' (#521.2202.2215), line 89, column 12: "allPosIndexes"
And the same for "allNegIndexes"
_____
Isn't there any easy way to just put the limit to 0 for the 2 colors?
I think the new proposal is way too complicated.
But if we can make it work, it is worth the effort.

类别

Help CenterFile Exchange 中查找有关 General Applications 的更多信息

产品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by