linewidth - plot matlab
Cambia el color de la lĂnea de trama 2D dependiendo del tercer valor (3)
Tengo un conjunto de datos que se parece a esto
140400 70.7850 1
140401 70.7923 2
140402 70.7993 3
140403 70.8067 4
140404 70.8139 5
140405 70.8212 3
Donde la primera columna corresponde al tiempo (intervalos de un segundo entre los puntos de datos) y estará en el eje x, la segunda columna se corresponde con la distancia y estará en el eje y. La tercera columna es un número (del uno al cinco) que es una calificación del movimiento.
Quiero hacer un diagrama que cambie el color de la línea entre dos puntos dependiendo de cuál fue el número del punto de datos anterior. Por ejemplo, quiero que la línea sea roja entre el primer y el segundo punto de datos porque el valor de calificación fue 1.
He visto muchas publicaciones sobre cómo hacer una escala móvil de colores dependiendo de un valor de intensidad, pero solo quiero 5 colores: (rojo, naranja, amarillo, verde y azul) respectivamente.
Intenté hacer algo como esto:
plot(x,y,{''r'',''o'',''y'',''g'',''b''})
Pero sin suerte.
¿Alguna idea de cómo abordar esto? Sin bucles si es posible.
¿Tiene Matlab R2014b o superior?
Entonces podría usar algunas características no documentadas introducidas por Yair Altman :
n = 100;
x = linspace(-10,10,n); y = x.^2;
p = plot(x,y,''r'', ''LineWidth'',5);
%// modified jet-colormap
cd = [uint8(jet(n)*255) uint8(ones(n,1))].'' %''
drawnow
set(p.Edge, ''ColorBinding'',''interpolated'', ''ColorData'',cd)
El efecto deseado se logró a continuación (simplificado):
indices(1).index = find( data( 1 : end - 1, 3) == 1);
indices(1).color = [1 0 0];
indices(2).index = find( data( 1 : end - 1, 3) == 2 | ...
data( 1 : end - 1, 3) == 3);
indices(2).color = [1 1 0];
indices(3).index = find( data( 1 : end - 1, 3) == 4 | ...
data( 1 : end - 1, 3) == 5);
indices(3).color = [0 1 0];
indices(4).index = find( data( 1 : end - 1, 3) == 10);
indices(4).color = [0 0 0];
indices(5).index = find( data( 1 : end - 1, 3) == 15);
indices(5).color = [0 0 1];
% Loop through the locations of the values and plot their data points
% together (This will save time vs. plotting each line segment
% individually.)
for iii = 1 : size(indices,2)
% Store locations of the value we are looking to plot
curindex = indices(iii).index;
% Get color that corresponds to that value
color = indices(iii).color;
% Create X and Y that will go into plot, This will make the line
% segment from P1 to P2 have the color that corresponds with P1
x = [data(curindex, 1), data(curindex + 1, 1)]'';
y = [data(curindex, 2), data(curindex + 1, 2)]'';
% Plot the line segments
hold on
plot(x,y,''Color'',color,''LineWidth'',lineWidth1)
end
También puede hacerlo con un truco que funciona con la versión de Matlab anterior a 2014b (ya en 2009a por lo menos).
Sin embargo, nunca será tan simple como esperabas (a menos que escribas un contenedor para una de las soluciones aquí puedes olvidarte de la plot(x,y,{''r'',''o'',''y'',''g'',''b''})
).
El truco es usar una surface
lugar de un objeto de line
. Las superficies se benefician de sus propiedades de CData
y de muchas características útiles para explotar los mapas de color y la textura.
Matlab surf
no maneja datos 1D, necesita una matriz como entrada, así que vamos a darlo simplemente duplicando cada conjunto de coordenadas (por ejemplo, xx=[x,x]
).
No obstante, no te preocupes, la superficie permanecerá tan delgada como una línea, por lo que el resultado final no es feo.
%% // your data
M=[140400 70.7850 1
140401 70.7923 2
140402 70.7993 3
140403 70.8067 4
140404 70.8139 5
140405 70.8212 3];
x = M(:,1) ; %// extract "X" column
y = M(:,2) ; %// same for "Y"
c = M(:,3) ; %// extract color index for the custom colormap
%% // define your custom colormap
custom_colormap = [
1 0 0 ; ... %// red
1 .5 0 ; ... %// orange
1 1 0 ; ... %// yellow
0 1 0 ; ... %// green
0 0 1 ; ... %// blue
] ;
%% // Prepare matrix data
xx=[x x]; %// create a 2D matrix based on "X" column
yy=[y y]; %// same for Y
zz=zeros(size(xx)); %// everything in the Z=0 plane
cc =[c c] ; %// matrix for "CData"
%// draw the surface (actually a line)
hs=surf(xx,yy,zz,cc,''EdgeColor'',''interp'',''FaceColor'',''none'',''Marker'',''o'') ;
colormap(custom_colormap) ; %// assign the colormap
shading flat %// so each line segment has a plain color
view(2) %// view(0,90) %// set view in X-Y plane
colorbar
lo conseguirá:
Como ejemplo de un caso más general:
x=linspace(0,2*pi);
y=sin(x) ;
xx=[x;x];
yy=[y;y];
zz=zeros(size(xx));
hs=surf(xx,yy,zz,yy,''EdgeColor'',''interp'') %// color binded to "y" values
colormap(''hsv'')
view(2) %// view(0,90)
le dará una onda sinusoidal con el color asociado al valor y
: