Usually this means that the working directory for python is not the directory that your *.py file is in.
To change the working directory for this script only, select “Run configurations”, set the correct working directory and hit “Run File.” Canopy usually will remember this selection the next time you open and try to run the file as as long as you don't move your script file or otherwise edit the directory tree on your computer.
To set Canopy to always use the script file's directory as the working directory, right click in the python window (the lower half of the editor window) and check the option “Keep Directory Synced to Editor.”
There are a few possibilities.
First, you may not have given good enough initial guesses for the fit parameters. While guessing “1” for everything works with linear fits and often even exponential fits, some functions can get lost in dark corners of math-space if you aren't careful.
Try plotting your guess along with your data to see if this might be a problem.
For guess fit parameters ofp01
and x-axis data oft
, you can use something like:
ax.plot(t, fitfunc(p01, t), label = 'guess')
When fitting multiple peaks or multiple functions, it is even more important to supply good initial guesses.
Second, it is possible you are not including a full model. Remember that data often sit on backgrounds (so include “+ A” for a constant or “+ A + Bx” for a linear background), and that sometimes we look at absorption spectra where we are dealing with a dip (negative coefficient) rather than a peak (positive coefficient). Double check that all features in the data are accounted for in your fit function.
Third, it is possible that you are trying to fit over too large a range of data. Remember when fitting Gaussians in your spectra that you need to truncate to only the data immediately around the peaks.
If yourx
data has 1000 points in it, you can select a range from those using[x100,900]
to select the 100th through 899th points in the list.
Or, if you want to set a filter based on your y data, you can create an array that selects only points meeting some condition. For example, to look only at data where y>10, you could use
data_filter = np.where(N > 100, True, False) new_y = y[data_filter] new_x = x[data_filter] new_dy = dy[data_filter]
Note that if you don't filter the x and dy arrays, Python may give you errors because you are trying to match up arrays of different lengths.
If you are trying to fit an exponential and get an error that reads:
Fit did not converge Success code: 3 Both actual and predicted relative reductions in the sum of squares are at most 0.000000 and the relative error between two consecutive iterates is at most 0.000000
check the x-range of your data, if some arguments are large (such as t = 1000) try compressing the range of your x-axis data by a factor of 10 or 100. The reason this may help is that Python may have issues when working with math involving very small numbers, such as $e^{-1000}$ . This may cause some of the values in the fitting algorithm to be rounded to zero, resulting in it thinking the initial guess is already a perfect fit.
On the other hand, large exponentials may also cause problems when they reach the limits of what Python can store in a floating point number. If you're working with numbers like $e^{600}$ or so this might be your issue.
This error is usually generated when the program tries to extract a value from the covariance matrix, but finds that the covariance matrix is undefined. (If we try to parse the text, this code is saying that the program cannot “get” an item from the list if the list doesn't exist.) The covariance matrix will not be defined if the fit is not able to make at least one full attempt at the fit. This is different from convergence; the program may try to fit 800 times before giving up, leaving us unconverged, but still generating a (meaningless, but nonetheless defined) covariance matrix. Instead, this error is appears either when the initial guesses lead to an illegal value in the fit function (e.g. an infinity or a negative under the square root) or, more commonly, when the fit function is passed a “list” rather than a numpy array.
Open a new cell and enterx
where x is the data you're trying to fit. This will show you what type of variable x is, along with some data and the length of the array.
This can happen if you try and add in formatting options to an error bar plot in the same way you would add them to a regular plot.
ax.plt()
expects x data, y data, and then formatting information in order.
ax.errorbar()
expects x data, y data, y errors, x errors, and then formatting if you're inputting variables sequentially.
To fix this, add fmt=
before the formatting string:
ax.errorbar(x,y,dy,fmt='ko')
This works because you're explicitly telling the errorbar function that 'ko' is the formatting variable fmt
.
When plotting, remember that python does not actually plot continuous functions, but instead plots lists of points. In order to give the illusion of a continuous function, we must plot a function over a sufficiently dense set of points and connect those points by lines.
In practice, this usually means building a fake array of points over which to plot the fit function which is more dense than the data from which the fit was performed. If we have data at points given by numpy array “x” which has been fit to function “fitfunc()”, we can plot the fit function on axis “ax” as follows:
X = linspace(x.min(), x.max(), 500) ax.plot(X, fitfunc(X))
This creates a numpy array of 500 linearly-spaced points from the minimum value of the x array to the maximum value of the x array and then plots the function over that array rather than the original x array.
For the following, we assume the figure is named “fig” and the axes are named “ax”.
You can set the x- or y-axis to plot logarithmically by using either "ax.set_xscale('log')"
or "ax.set_yscale('log')"
. Both instances must appear after the data is plotted, but before saving a file or using “show()
”.
You can set the x- or y-axis range independently using either “ax.set_xlim([_xstart_,_xstop_])
” or “ax.set_ylim([_ystart_,_ystop_])
” where xstart, etc. are the range limits.. Both instances must appear after the data is plotted, but before saving a file or using “show()”.
You can set the legend position by using the optional argument “loc” when you add the legend. Values include “upper left”, “upper center”, “upper right”, “center”, “lower left”, “lower center”, and “lower right”. For example,
ax.legend(loc=“upper left”)
Your text annotation is a long text string, so you insert numbers into that string by using the percent sign as a place holder (optionally with appropriate formatting information directly following it). The values used to fill those place holders are drawn from a list of variables placed after another percent sign which immediately follows the end of the string. An example:
x = 1111 y = 55.45462 print('The final position of the ball was at x = {:d} and y = {:.3f}'.format(x, y))
In this example, we make two replacements. The first pair of curly brackets is replaced by the value of the first variable in the list, “x”; it is formatted as a decimal by the `:d` key value. The second pair of curly brackets is replaced by the second value in the list, “y”; it is formatted as a floating point number with three digits shown after the decimal place.
Options for string replacement include the following (where NONE means no formatting information is given after the percent sign):
When the variable is an integer number: | |
'i' or 'd' | Decimal (base 10) format |
'b' | Binary (base 2) format |
'x' | Hexidecimal (base 16) format with lower-case letters |
'X' | Hexidecimal (base 16) format with upper-case letters |
NONE | Same as 'd' |
When the variable is a floating point (decimal) number: | |
'i' | Formats as an integer; no decimal place |
'.#f' or '.#F' | Fixed point notation with a number of digits after the deicmal given by #. (If no number is given, the default is 6.) |
'.#e' | Scientific notation format with a number of digits after the decimal given by #. (If no number is given, the default is 6.) |
'.#E' | Same as 'e', but with a capital E for scientific notation |
'g' | “General” format; program will determine how many digits to show and whether to show in fixed point or scientific notation |
'G' | Same as 'g', but with a capital E for scientific notation |
NONE | Same as 'g' |
help('FORMATTING')
will bring up this information as well.
Inside any text string, you can enter the LaTeX math environment by enclosing your text with dollar signs, $. For example,
axis_title = 'Position-squared, $x^2$ (square-km)'
Symbols and more complicated constructions (including fractions, sums, square roots, etc.) can also be done in the math environment, but it is good practice to use two back-slashes where one is normally called for. (E.g. “\\sqrt{…}” instead of “\sqrt{…}”) This is because there are several python or general computing commands which use a single backslash (e.g. “\t” for tab or “\n” for new line) and python may interpret the start of your LaTeX command incorrectly. For example, “\tan” will not yield the tangent function, but instead “[tab]an”.
If you want to preview your LaTeX outside of a plot, you can use IPython's display and Latex modules:
from IPython.display import display, Latex axis_title = 'Position-squared, $x^2$ (square-km)' print(axis_title) display(Latex(axis_title))
The following is a list of possible plot markers and a description of their shape:
Marker | Description |
. | point |
, | pixel |
o | circle |
v | triangle_down |
^ | triangle_up |
< | triangle_left |
> | triangle_right |
1 | tri_down |
2 | tri_up |
3 | tri_left |
4 | tri_right |
8 | octagon |
s | square |
p | pentagon |
* | star |
h | hexagon1 |
H | hexagon2 |
+ | plus |
x | x |
D | diamond |
d | thin_diamond |
| | vline |
_ | hline |
TICKLEFT | tickleft |
TICKRIGHT | tickright |
TICKUP | tickup |
TICKDOWN | tickdown |
CARETLEFT | caretleft |
CARETRIGHT | caretright |
CARETUP | caretup |
CARETDOWN | caretdown |
“None” | nothing |
None | nothing |
” “ | nothing |
“” | nothing |
See The official page for a complete listing