How can I com[act my script by making it run up to an nth variable

1 view (last 30 days)
I am looking to plot multiple curves in 3D, the curves consist of 3 variables each; xn, kn and zn, such that the first curve is plotted from x1, k1 and z1. The way i am plotting the curves in 3D can be seen below and hopefuly this provides good context asto what im doing.
I have written a script that i intend to use on multiple sets of curves with varying numbers of curves, the problem parts are;
z1=rot90(v1);
z2=rot90(v2);
z3=rot90(v3);
z4=rot90(v4);
z5=rot90(v5);
z6=rot90(v6);
z7=rot90(v7);
and
plot3(x1, k1, z1, 'linewidth', 2, 'color', 'k');
plot3(x2, k2, z2, 'linewidth', 2, 'color', 'k');
plot3(x3, k3, z3, 'linewidth', 2, 'color', 'k');
plot3(x4, k4, z4, 'linewidth', 2, 'color', 'k');
plot3(x5, k5, z5, 'linewidth', 2, 'color', 'k');
plot3(x6, k6, z6, 'linewidth', 2, 'color', 'k');
plot3(x7, k7, z7, 'linewidth', 2, 'color', 'k')
grid on
surf([x1;x2], [k1;k2], [z1;z2]);
surf([x2;x3], [k2;k3], [z2;z3]);
surf([x3;x4], [k3;k4], [z3;z4]);
surf([x4;x5], [k4;k5], [z4;z5]);
surf([x5;x6], [k5;k6], [z5;z6]);
surf([x6;x7], [k6;k7], [z6;z7]);
is there a way i can get this script to create a variable called zn by rotation a variable called vn up to the nth vn variable? Is there also a similar thing i can do for plotting and drawing the surfaces as right now i am stuck with editing the script each time i am changing the number of curves. I have zero experience with coding so hopefully i have framed this well enough for it to be understandable and sorry if its just trivial.
Thanks in advance.
  1 Comment
Stephen23
Stephen23 on 23 Jul 2024
Edited: Stephen23 on 23 Jul 2024
"is there a way i can get this script to create a variable called zn by rotation a variable called vn up to the nth vn variable?"
Yes there are ways, if you really want to force yourself into writing slow, complex, inefficient, insecure, obfuscated, buggy code that is hard to debug:
The simple, efficient, recommended approach is to use indexing. You should use indexing. So far there is nothing in your description and examples that would prevent you from using indexing.
Indexing is a MATLAB superpower. Use it.

Sign in to comment.

Accepted Answer

Shubham
Shubham on 23 Jul 2024
Hi Rowan,
To make your script more flexible and able to handle varying numbers of curves, you can use loops and dynamic variable naming. Here's a structured way to achieve this:
Step 1: Rotate the Variables
Instead of manually rotating each variable, use a loop to handle the rotation for all variables up to the nth variable.
Step 2: Plot the Curves
Use a loop to plot each curve dynamically.
Step 3: Draw the Surfaces
Similarly, use a loop to draw the surfaces between consecutive curves.
Here's how you can implement this in MATLAB:
% Define the number of curves
numCurves = 7; % Change this number as needed
% Initialize cell arrays to store x, k, and z variables
x = cell(1, numCurves);
k = cell(1, numCurves);
z = cell(1, numCurves);
v = cell(1, numCurves); % Initialize cell array for v variables
% Load your x, k, and v data here
% Example data for demonstration purposes
for i = 1:numCurves
x{i} = linspace(0, 10, 100); % Replace with your actual x data
k{i} = linspace(0, 5, 100); % Replace with your actual k data
v{i} = sin(linspace(0, 2*pi, 100)) + i; % Replace with your actual v data
end
% Rotate v variables and store in z
for i = 1:numCurves
z{i} = rot90(v{i});
end
% Plot the curves
figure;
hold on;
for i = 1:numCurves
plot3(x{i}, k{i}, z{i}, 'linewidth', 2, 'color', 'k');
end
% Draw the surfaces between consecutive curves
for i = 1:(numCurves - 1)
% Ensure x, k, and z are matrices for surf
[X, K] = meshgrid(x{i}, k{i});
Z1 = interp1(x{i}, z{i}, X(1, :));
Z2 = interp1(x{i}, z{i+1}, X(1, :));
Z = [Z1; Z2];
surf(X, K, Z);
end
grid on;
hold off;
Explanation:
Initialization:
  • numCurves specifies the number of curves.
  • Cell arrays x, k, z, and v are initialized to store the respective variables.
Data Loading:
  • The example uses linspace and sin to generate sample data. Replace these lines with your actual data loading or assignment code.
Rotation Loop:
  • The loop rotates each v variable and stores it in the corresponding z cell.
Plotting Loop:
  • The loop plots each curve in 3D.
Surface Loop:
  • The loop creates matrices X and K using meshgrid to ensure that x and k are matrices.
  • Z1 and Z2 are created by interpolating z{i} and z{i+1} over the grid defined by X.
  • The Z matrix is constructed by stacking Z1 and Z2.
  • surf is used to plot the surface between consecutive curves.
Note:
Replace the example data generation with your actual data. For instance, if you have x1, k1, v1, x2, k2, v2, etc., you should load them accordingly:
x{1} = x1; k{1} = k1; v{1} = v1;
x{2} = x2; k{2} = k2; v{2} = v2;
% and so on...
This approach makes your script adaptable to any number of curves by simply changing the numCurves variable.
  1 Comment
Rowan
Rowan on 23 Jul 2024
Thank you for this and especially taking the effort for writing the explanations out, i think i can see what it is doing. I have tried to replace your example data with some of my own and hopefully this is in the correct format. However i am experiencing trouble with the plot function where if i try
plot3(x{i}, k{i}, z{i}, 'linewidth', 2, 'color', 'k')
plot3(x, k, z, 'linewidth', 2, 'color', 'k')
i get the errors; "vectors must be the same length" and "Not enough input arguments" respectivley. if i had to guess, i am not inserting my own data correctly however i am at a loss so any pointers would be greatly appreciated. Below is the entire script, the appearance of variables "l" and "d" is due to d being my raw x data that needs to have a logarithm taken of and then rotated. Thurthermore any advice on any resources i could use to learn how to do more stuff like this would be great.
numCurves = 7;
x = cell(1, numCurves);
l = cell(1, numCurves);
d = cell(1, numCurves);
k = cell(1, numCurves);
z = cell(1, numCurves);
v = cell(1, numCurves);
d{1} = d1; k{1} = k1; v{1} = v1;
d{2} = d2; k{2} = k2; v{2} = v2;
d{3} = d3; k{3} = k3; v{3} = v3;
d{4} = d4; k{4} = k4; v{4} = v4;
d{5} = d5; k{5} = k5; v{5} = v5;
d{6} = d6; k{6} = k6; v{6} = v6;
d{7} = d7; k{7} = k7; v{7} = v7;
for i = 1:numCurves
z{i} = rot90(v{i});
end
for i = 1:numCurves
l{i} = log10(d{i});
end
for i = numCurves
x{i} = rot90(l{i});
end
figure;
hold on;
for i = 1:numCurves
plot3(x{i}, k{i}, z{i}, 'linewidth', 2, 'color', 'k');
end
for i = 1:(numCurves - 1)
[X, K] = meshgrid(x{i}, k{i});
Z1 = interp1(x{i}, z{i}, X(1, :));
Z2 = interp1(x{i}, z{i+1}, X(1, :));
Z = [Z1; Z2];
surf(X, K, Z);
end
grid on;
hold off;

Sign in to comment.

More Answers (1)

Steven Lord
Steven Lord on 22 Jul 2024
Can you dynamically create variables with numbered names like z1, z2, z3, etc.? Yes.
Should you do this? The general consensus is no. That Discussions post explains why this is generally discouraged and offers several alternative approaches.

Categories

Find more on MATLAB in Help Center and File Exchange

Tags

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!