Making scatter plots from structs in MATLAB - matlab

I'm trying to write a bit of code of to make MATLAB scatter plots from variables in a structure. I want to give the code the name of the structure (there will be many of these structures) and then get it to make a scatter plot of two variables. When I try the code below I get an error message saying, "??? Error: File: make_graphs.m Line: 6 Column: 9
The input character is not valid in MATLAB statements or expressions."
str2stuct= input('Please enter the string for the struct e.g. TMB_RUN_1_data:');
test1=strcat(str2stuct,'.NDROP_max');
test2=strcat(str2stuct,'.input_kappa');
scatter($(test2), $(test1))
I thought that the error message probably meant that I was using the dollar sign in a way which MATLAB doesn't approve of (I've yet to find much use for $ in MATLAB).
I tried it like this:
str2stuct= input('Please enter the string for the struct e.g. TMB_RUN_1_data:');
test1=strcat(str2stuct,'.NDROP_max');
test2=strcat(str2stuct,'.input_kappa');
scatter((test2),(test1))
And got this error:
"??? Error using ==> scatter at 51
Must supply X and Y data as first arguments.
Error in ==> make_graphs at 6
scatter((test2),(test1)) "
I tried it with changing the last line as shown below but got the same error as with the brackets:
scatter(test2,test1)
If I use the literal name as below it works fine.
scatter(TMB_RUN_1_data.NDROP_max,TMB_RUN_1_data.input_kappa)
I've tried a bunch of other things but I am not getting it. I've tried the mathworks pages on scatter but there are no examples that are close to what I am doing. I am really really stuck.
EDIT: I have found a solution but I am aware that this is not considered best practice. If you can simply explain how to do this better that would be good. Answers should be aimed at a moron in a hurry, not an experienced programmer.

Making this the last line works:
scatter(eval(test2),eval(test1))
I am aware that 'eval' is frowned upon and so this probably isn't a good long term answer, works for now. This seems to be the way to get MATLAB to actually read the contents of the strings test1 and test2 into the lines in question.

Related

Issues with MATLAB butter

I am using MATLAB R2015 and cannot implement 'butter' without getting an error related to too many output arguments from the polyfit part of the script. I have used the same implementation for years with other versions of MATLAB.
Example:
[b, a] = butter(2,[.15,.3]);
Error using poly
Too many output arguments.
Error in zp2ss (line 127)
den = real(poly(p(i:i+1)));
Error in butter (line 97)
[a,b,c,d] = zp2ss(z,p,k);
I get the same error implementing the examples in the help documentation.
Just a guess but is there any chance you've defined your own poly function? which('poly') should point to some Matlab directory unless you've defined it elsewhere, potentially as a variable?. For me on a newer version that path is something like $MATLAB/toolbox/matlab/polyfun/poly.m You can also edit the poly function edit poly and verify that there is one output argument for the function.
Also, I'd advise against ever writing decimal numbers without a leading zero. It took me way to long to figure out what [.15,.3] was. Instead write [0.15,0.3] or even just [0.15 0.3] Edit: I just realized that is an example in Matlab ... my point stands but the toolbox author should know better ...

MatLab latex title doesn't work for powers (^)

In MatLab (R2015a), I want to style the title of my plots using latex.
This is working fine for some functions, but not if there's a power in the equation.
The below code works, and shows a formatted title to the right, and an unformatted title to the left.
It shows the warning:
Warning: Error updating Text.
String must have valid interpreter syntax: y = x^2
syms x y
eq = y == x^2;
subplot(1,2,1)
ezplot(eq)
title(latex(eq),'interpreter','latex')
eq = y == x+2;
subplot(1,2,2)
ezplot(eq)
title(latex(eq),'interpreter','latex')
EDIT:
I just found out I can get it to work by appending $ on both sides. But it seems weird that I would have to do this.
So this works:
title(strcat('$',latex(eq),'$'),'interpreter','latex')
Solution
The problem can be solved easily by adding $-signs before and after the generated LaTeX-expression. So you can change your «title-lines» to:
title(['$',latex(eq),'$'],'interpreter','latex')
An alternative is to use strcat as proposed in your question.
Explanation
Since you basically answered the question yourself already, I'm going to explain why it happened. Hopefully after reading this, it's no longer 'weird' behaviour. If you choose to use the LaTeX-interpreter in Matlab, you really get a LaTeX-interpreter. This means that the provided string must be valid LaTeX-syntax.
Using ^ outside a math-environment is considered invalid syntax because it is a reserved character in LaTeX. Some interpreters automatically add the $ before and after in this case, but throw a warning at the same time.
The output of the latex-function in Matlab is provided without the $-signs. This way you can combine outputs and concatenate if needed without creating a mess with $-signs.
To change to the math-environment in LaTeX you can use the already mentioned shortcut $...$. An alternative way is to use \begin{math} your_equation \end{math}. It produces the same result for your equations and can be used here for demonstration purposes. The following line would do the same job, but is a bit longer to write:
title(['\begin{math}',latex(eq),'\end{math}'],'interpreter','latex')
Now, the reason why only one of your equations is displayed correctly, lies in the invalid character ^ in y = x^2. Matlab then chooses interpreter none and therefore displays the string unformatted. The +-sign in y = x + 2 is valid outside a math-environment, so it gets displayed correctly (but is not interpreted in a math-environment).

for loop range syntax

I spent a couple of hours debugging a problem that I would have thought would have been a syntax error.
a = zeros(3);
for i=1:1size(a,2) % note the missing colon between 1 and size(a,2)
i
end
The following only displays
ans = 3
1
Essentially, it seems Matlab/Octave parses the above as:
for i=1:1
size(a,2)
i
end
Note however that
i=1:1size(a,2)
produces a syntax error. Is there a good reason that Matlab/Octave has this for loop syntax? Is there something that it's supposed to make easier? Just curious if anyone else has any thoughts about it. Thanks.
It is indeed a bit of a surprise that Matlab's syntax allows this. I don't know why this is allowed. One reason might be to allow for-loops on one line:
>> for i=1:3 disp(i);end
1
2
3
But interestingly, removing the space is not allowed:
>> for i=1:3disp(i);end
for i=1:3disp(i);end
|
Error: Unexpected MATLAB operator.
This reason for this is probably that a number followed by d is another way of writing a floating point number (3d10 == 3e10), so the parser/tokenizer initially thinks you define a number, but then gets confused when it sees the i. Daniel's example with fprintf does work, since a number followed by an f is not a valid number, so the tokenizer understands that you started a new token.
I guess that many years ago (>30?), when they defined matlab's syntax, they did not foresee that this could introduce this kind of hard-to-spot problems. I guess matlab was originally written by engineers for engineers, and not by someone who knows how to design a general purpose programming language. Other languages like C or Python use punctuation to separate loop conditions from loop body, so there is no ambiguity. I don't know if it is still possible to correct Matlab's syntax, since it might break old code that relies on the current behavior.
At least, if you use a recent version of Matlab, the editor warns for various problems in your code. Paying attention to the small red dashes in the right hand border could have saved you a few hours of debugging time (but maybe you were using octave). I try to make it a habit to fix all the warnings it indicates. For your code, it shows the following:
Your code is equivalent to
a = zeros(3);
for i=1:1
size(a,2)
i
end
There are some places where everyone would use newline or white space, but the parser itself does not require.
A minimal loop:
for i=1:3fprintf('%d',i),end
but I recommend to use at least a comma seperated version, everything else is horrible to read:
for i=1:3,fprintf('%d',i),end

Wavelet transform using dwt3 in MATLAB

I have a project to transform an image using dwt.
I successfully done it using function dwt2, and now I try to use function dwt3 by changes some code from the function dwt2 (add more subband: 8 subbands). Unfortunately, an error comes out, which said "Too many output arguments".
My question is, what is the right way to write MATLAB code for dwt3? Is it not same as dwt2, just add more subbands?
Just by looking at the official documentation for dwt2 and dwt3, I see that dtw3 has only 1 output variable, whereas dtw2 has 4.
I assume you just replaced the string dtw2 in your code to dwt3, without paying attention to the amount of allowed output variables. So there you go, that's where the error "too many output variables" comes from...
If dwt3 only returns the transformed vector, cut the number of output variables to 1, and I'm sure the error will away:
Y = dwt3(X, 'db2');
Here I transformed X using dwt3 with the Daubechies 2-tap wavelet, and stored the result in Y.
P.S
You need to show more code if you want more productive, helpful answers...

Using GraphViz in MATLAB

I tried to plot graphs on MATLAB using GraphViz, using this GraphViz interface.
I keep getting this error:
>> [x,y]=draw_dot(G)
??? Attempted to access node_pos(2); index out of bounds because numel(node_pos)=1.
Error in ==> dot_to_graph at 94
y(lst_node) = node_pos(2);
Error in ==> draw_dot at 30
[trash, names, x, y] = dot_to_graph(tmpLAYOUT); % load NEATO layout
Whats really bugging me is that it worked great before (on my old computer).
Any idea how to solve this problem?
After debugging, I find the solution.
Just find the line 92 in dot_to_graph.m, as written:
[node_pos] = sscanf(line(pos_pos:length(line)), ' pos = "%d,%d"')';
Change the %d,%d to %f,%f. Because there are float numbers in the dot file.
This is difficult to answer completely since you are not giving us the G you are using, so we can't reproduce your problem directly; I'll attempt to answer anyhow "on the dry":
The error messages you get mean that the temporary DOT files created by neato in draw_dot can not be read properly; a line in the dot file which is parsed by dot_to_graph using the format string pos = "%d,%d" is expected to contain two numbers, e.g pos ="42,3", but MATLAB's sscanf only reads one number from that line.
Is it possible that your new computer uses a different language setting, i.e. using a decimal comma instead of a decimal point? This might cause Matlab to read the two numbers as one, not sure how sscanf adapts to local decimal point settings.
Otherwise, are you still using the same version of neato as before? Could it be that its output format has changed in some way?
The best way to find out might be to set a debugging break point in the offending line 94 ([node_pos] = sscanf(line(pos_pos:length(line)), ' pos = "%d,%d"')';) and check what line(pos_pos:length(line)) evaluates to.