OriginLab create curve fitting - originlab

I need to fit the following equation onto a plot in origin,
y = y_0 + (ka)/(((x-x_c)^2 + a^2)^(3/2))
where a is known to be 0.105,
y_0 is the baseline, x_c is the peak centre. Can anyone enlighten me on how to create such a fitting function?
Thanks!

If the answer is still of interest:
It can be done with the nonlinar fitting tool using a user-defined function. (See Origin-Help: NLFit for an overview)
To sum up the steps:
Open NLFit dialog box (Ctrl + Y)
For function select 'new ...' and follow dialog
Select 'Explicit' and 'Expression', press 'Next'
Set y_0, ka, and x_c as parameters and add a as constant. Press 'Next'
Copy Function y_0 + (ka)/(((x-x_c)^2 + a^2)^(3/2)) in the function box
Give reasonable start values for your parameters and set the constant a to 0.105
In the next pages you can set limits and more, but this is optional. You can 'Finish' at this point
Back in the fit dialog the data should be already set, if the corresponding plot to fit was active during opening of the dialog.
Change to the 'parameter' tab to see the results and start the fitting with the 'fit til convergence' button to the left of the 'Fit' button
If it does not converge, start playing around with the start values of the parameters

Related

MatLab GUI plotting a line that updates with button press

So I'm working on MatLab GUI assignment right now.
It's basically an estimation game. In every trial the user guesses the correlation displayed on the left axes. When they click submit my code calculates the absolute value of the difference between their estimation and the actual correlation.
So far so good.
On the right axes I want to plot a line that updates every time they click "submit". The x-coordinate would be the trial # and the y-coordinate would be the absolute difference previously mentioned.
I can plot this information successfully using points instead of a line by using "scatter" or "plot", but when I try to make it a line, nothing appears, although the axis does seem to update...
Both of the following codes work if the marker is '.' or 'o' or 's' or 'x' ... literally any marker.. but I can't get it to connect the dots... I've messed around with trying to use animated line and drawnow but that didn't work out for me either..
plot(handles.trial, handles.diff(handles.trial),'-.'); hold on; %plot trialwise absolute differences
or
scatter(handles.trial, handles.diff(handles.trial),'-.'); hold on; %plot trialwise absolute differences
**Problem solved!
see the solution below
Solution:
Store all of the relevant data in a matrix handles.DATA. For this to work there needed to be something in there before the first trial so during initialization I set handles.DATA = [0 0] and then with the button-press (submit) that ends a trial, the data from that trial got concatenated into the data matrix: handles.DATA = vertcat(handles.DATA, [x y]). Below this I could do the plot that I wanted to: plot(handles.DATA(:,1), handles.DATA(:,2),'Color','r'
*note: don't hold on because then you will have lines stacking on each other.
**also if you don't specify line color, the line will become a different color every time you click "submit" because this is generating a new line every time based off the updated information.

Matlab interactive calculation of slope between two points

I create a figure with toggle button on its toolbar by uitoggletool. The callback function for it is shown below:
function calc_slope(handle,event)
on = get(handle,'State');
if strcmpi(on,'on') || strcmpi(on,'off'),
xy=imline;
addNewPositionCallback(xy,#(xy)...
title(['\DeltaY/\DeltaX = ',num2str((xy(4)-xy(3))/(xy(2)-xy(1))),...
'[\DeltaX = ',num2str(xy(2)-xy(1)),...
',\DeltaY = ',num2str((xy(4)-xy(3))),']']));
end
As you can see, I'm trying to calculate the slope between two points on a curve. The code is something I found in the web that's pretty close to what I'm trying to. The 'addNewPositionCallback" is executed in both 'On' and 'Off' state, but it's merely a means to repeat the process as many times as a user wants. What I really want to do is number 4 and 5 below.
What I really want to do is as follows:
"Draggable" points "snapped" to the nearest curve
The connecting line shows
Delta X, delta Y, and the slope provided in a "text box" drawn near
the curve
Draw as many lines as needed while in the 'On' state
Delete all lines and 'text' boxes when toggle button is set to 'Off'
The imline function gives a bunch of features such as different line colors. I can care less on those. The major "wants" are the snapping and the text box.
Your help will be greatly appreciated.
Thank you,
Eric

Control Point Registration using matlab -'fitgeotrans' function

I'm new to Matlab and I'm trying to do a Control Point Registration using their guide: http://www.mathworks.com/help/images/point-mapping.html
It works fine until the 'fitgeotrans' function where I get an error that saying:
'Undefined function or variable 'input_points'.
I read the Matlab help and the previous "cpselect" function gives me two nX2 arrays with the coordinates which are saved (by the 'cpselect' function) in two array variables 'input_points' and 'base_points'. So, I really don't understand why the next function can't "See" them and considers them 'Undefined'.
My code is attached bellow. Thank you for your help.
function [Y] =EBL
ReferenceImg=imread('GFI.jpg'); %This is the fixed image
CroppedImg=imcrop(ReferenceImg); %Crop the image
close %close the imcrop window
ResizedIReferenceImg= imresize(CroppedImg,[1000 1000]); %re-size the fixed image
t=imagesc(ResizedIReferenceImg); %Set transparency of fixed image
set(t,'AlphaData',0.5);
hold on
I = imread('GF.bmp'); %This is the moving picture
MovingImg = imrotate(I,-5,'nearest','crop'); % Rotate the moving picture cw
ResizedMovingImg= imresize(MovingImg,[1000 1000]); %re-size the moving image
h=imagesc(ResizedMovingImg); %Set transparency of moving image
set(h,'AlphaData',0.6);
close
cpselect(ResizedMovingImg,ResizedIReferenceImg); %Alignment
tform = fitgeotrans(input_points,base_points,'NonreflectiveSimilarity');
The problem is that MATLAB doesn't, by default, wait for you to be done before moving on from cpselect. So it simply moves on from cpselect to tform before you have a chance to actually select any points, at which point input_points doesn't yet exist. You have to set the Wait parameter, and doing so also affects the outputs. With Wait on, call cpselect something like this:
[input_points,base_points] = cpselect(MovingImg,ReferenceImg,'Wait', true);
When calling cpselect in this way, you will not have the "Export Points to Workspace" option. Instead, the selected points will be output into the variables input_points,base_points when the cpselect window is closed.

any way to have mouse stick to a curve in matlab?

I have a java program with a Gaussian plotted in the range -3 to 3 (f = exp(-x^2/3)). I capture the mouse event and have the mouse can only move along the curve so to pick up the value (f) and the corresponding x. Is that possible to implement the same thing in matlab? I search for mouse event in matlab but seems it doesn't have any low-level mouse control or even response.
As suggested by A. Donda, I tried datacursormode. If I have two curves shown on the same figure, I can easily trace the position of the mouse on either curve, I wonder if it is possible to capture the event upon the tracing so I can return the value of the other curve at the same x-coordinate while I am tracing the other curve? Or if it possible to change the way or content the yellow tip shown? What I really interesting is the sum or difference or product of the function values from two curve at the same x position.
Not exactly the same thing, but you can use "Tools / Data Cursor" in the figure window, also accessible by the "yellow note with crosshairs" icon in the toolbar, or the function datacursormode.
You can't easily set the mouse position with matlab (see here for an example). As mentioned by #A. Donda, the straightforward solution is to use the data cursor.
Set the "stick-to-curve" behavior with your mouse
With datacursormode on, you can right click on the axes and set Selection Style to Mouse Position. Then, select a first point on the curve. A data tip containing (x,y) will appear. Select a second point but keep the mouse button down: the data cursor will stick to the curve and will follow the mouse.
Set the "stick-to-curve" behavior programatically
Get the handle of datacursormode and set the SnapToDataVertex property to off before calling datacursormode on
cursorMode = datacursormode(gcf);
set(cursorMode, 'SnapToDataVertex', 'off');
datacursormode on

How can I order items in a Matlab legend via the figure editor?

I've created a histogram with multiple sets of data. The data sets are color imgages converted to grayscale and taken over a given time period (e.g. pic 1 # time=0, pic 2 # time=5min, etc.) which is why I need the legend entries to show up in a specific order. When I put the legend in, the entries are scattered around in no specific order and I can't figure out how to get the entries switched up the way I need them.
In 2017a and higher (using part of the answer by Peter M above)
Select "Edit Plot" with the standard arrow button in the toolbar. This will allow you to select plot lines.
Select the plot line you want to appear first in the legend.
Use Ctrl-X (or whatever on OS X,Linux) to "Cut" the Plot line.
Create a new figure (File -> New -> Figure).
Use Ctrl-V (or whatever on OS X, Linux) to "Paste" the Plot line in the new figure.
"Cut" the Plot line in the new figure.
"Paste" the Plot line in the original figure.
Repeat steps 2-6 for every plot line, in the order that you want
them to appear in the legend. Right click on the legend and
"Refresh"
If you are regenerating the plot often of course it is probably a good idea to make sure that the script puts them in the correct order. Luis Mendo provided an answer here, but his answer to a slightly different wording was a little more detailed: how to change the sequence of the legend.
Pre 2017a Only! It seems that 2017a breaks this behavior, so the following trick does not work in the latest versions.
To answer your specific question, here is a neat trick if you are just doing this once in awhile on a plot that doesn't have many lines, and only want to use the Figure Editor...
Select "Edit Plot" with the standard arrow button in the toolbar. This will allow you to select plot lines.
Select the plot line you want to appear first in the legend.
Use Ctrl-X (or whatever on OS X, Linux) to "Cut" the Plot line.
Use Ctrl-V (or whatever on OS X, Linux) to "Paste" the Plot line.
Repeat steps 2-4 for every plot line, in the order that you want them to appear in the legend.
Right click on the legend and "Refresh"
You can get a handle to each plotted object, and in the legend use the handles to control which string applies to which plotted object.
Example:
h1 = plot(1:5, 1:5, 'r');
hold on
h2 = plot(1:5, 2:6, 'b');
legend([h1 h2],'First red','Second blue')
The answer above also works for R2017a and higher...here is a little bit more general example:
x = 1:10;
y1 = x;
y2 = 2*x;
y3 = 3*x;
y4 = x.^2;
figure
plot(x, y1, x, y2, x, y3, x, y4);
lh = legend('y = x', 'y = 2*x', 'y = 3*x', 'y = x.^2');
legendEntries = get(gca,'legend')
plotHandles = get(gca,'children')
legendEntries = legendEntries.String;
newOrder = [3,4,1,2];
legend([plotHandles(newOrder)],legendEntries{newOrder})
flipud(h) or fliplr(h) to change complete order of the array up-down oder left-right
Through try and error I found this easy fix:
1) select the plot line that should be at position 1 (at the top)
2) Strg + X
3) Strg + V in the same plot figure
Repeat step 2 and 3 about 3 or 4 time. This will result in the plot beeing at the bottom of the legend. Now select the plot that should be at the 2nd position, again Step 2 and 3 a couple times. The previous plot moves one place up, the 2nd picked plot is now at the bottom.... continue with the rest of the plots the same way