Defining Octave Functions - function

I am working on a school project with Octave for calculating and plotting velocity/acceleration graphs.
I have been trying to create a subplot function so that I won't have to hardcore it for every subplot as such
subplot(3, 1, 1);
plot(time, accn);
grid;
title('Acceleration vs Time')
xlabel('Time, (s)')
ylabel('Acceleration, (m/s^2)')
subplot(3, 1, 2);
plot(time, velocity);
grid;
title('Velocity vs Time');
xlabel('Time, (s)');
ylabel('Velocity, (m/s)');
Is it possible to create a function akin to this
subplot = subplotFunction(row, column, xaxis, yaxis, header, xaxisLabel,
yaxisLabel)
subplot(3, row, column);
plot(xaxis, yaxis);
grid;
title('header')
xlabel('xaxisLabel')
ylabel('yaxisLabel')
endfunction
And then call it like this?
subplot = subplotFunction(1, 1, time, accn, 'Acceleration vs Time', 'Time, (s)', 'Acceleration, (m/s^2)')
I am quite new to using functions so my apologies :(

1;
function subplotFunction(row, column, idx, xaxis, yaxis, header, xaxisLabel, yaxisLabel)
subplot (row, column, idx);
plot (xaxis, yaxis);
grid on;
title (header)
xlabel (xaxisLabel)
ylabel (yaxisLabel)
endfunction
subplotFunction (3, 1, 1, 1:10, 11:20, "foo", "bar", "baz")
subplotFunction (3, 1, 2, 1:10, 11:20, "huhu", "haha", "hoho")
x = linspace (0, 10, 100);
subplotFunction (3, 1, 3, x, sin(x), "world", "boo", "doo")
print ("out.png")
gives

Related

Return a value of dictionary where a variable is inbetween keys or values

I have some data that I think would work best as a dictionary or JSON. The data has an initial category, a, b...z, and five bands within each category.
What I want to be able to do is give a function a category and a value and for the function to return the corresponding band.
I tried to create a dictionary like this where the values of each band are the lower threshold i.e. for category a, Band 1 is between 0 and 89:
bandings = {
'a' :
{
'Band 1' : 0,
'Band 2': 90,
'Band 3': 190,
'Band 4': 420,
'Band 5': 500
},
'b' :
{
'Band 1' : 0,
'Band 2': 500,
'Band 3': 1200,
'Band 4': 1700,
'Band 5': 2000
}
}
So if I was to run a function:
lookup_band(category='a', value=100)
it would return 'Band 3' as 100 is between 90 and 189 in category a
I also experimented with settings keys as ranges but struggled with how to handle a range of > max value in Band 5.
I can change the structure of the dictionary or use a different way of referencing the data.
Any ideas, please?
You can structure your data a little bit differently (using sorted lists instead of dictionaries) and use bisect module. For example:
from bisect import bisect
bandings = {
'a': [0, 90, 190, 420, 500],
'b': [0, 500, 1200, 1700, 2000]
}
def lookup_band(bandings, band, value):
return 'Band {}'.format(bisect(bandings[band], value))
print(lookup_band(bandings, 'a', 100)) # Band 2
print(lookup_band(bandings, 'b', 1700)) # Band 4
print(lookup_band(bandings, 'b', 9999)) # Band 5

Curve Fitting past last data point(s)

I am trying to fit a curve to a set of data points but would like to preserve certain characteristics.
Like in this graph I have curves that almost end up being linear and some of them are not. I need a functional form to interpolate between the given data points or past the last given point.
The curves have been created using a simple regression
def func(x, d, b, c):
return c + b * np.sqrt(x) + d * x
My question now is what is the best approach to ensure a positive slope past the last data point(s) ??? In my application a decrease in costs while increasing the volume doesn't make sense even if the data says so.
I would like to keep the order as low as possible maybe ˆ3 would still be fine.
The data used to create the curve with the negative slope is
x_data = [ 100, 560, 791, 1117, 1576, 2225,
3141, 4434, 6258, 8834, 12470, 17603,
24848, 35075, 49511, 69889, 98654, 139258,
196573, 277479, 391684, 552893, 780453, 1101672,
1555099, 2195148, 3098628, 4373963, 6174201, 8715381,
12302462, 17365915]
y_data = [ 7, 8, 9, 10, 11, 12, 14, 16, 21, 27, 32, 30, 31,
38, 49, 65, 86, 108, 130, 156, 183, 211, 240, 272, 307, 346,
389, 436, 490, 549, 473, 536]
And for the positive one
x_data = [ 100, 653, 950, 1383, 2013, 2930,
4265, 6207, 9034, 13148, 19136, 27851,
40535, 58996, 85865, 124969, 181884, 264718,
385277, 560741, 816117, 1187796, 1728748, 2516062,
3661939, 5329675, 7756940, 11289641, 16431220, 23914400,
34805603, 50656927]
y_data = [ 6, 6, 7, 7, 8, 8, 9, 10, 11, 12, 14, 16, 18,
21, 25, 29, 35, 42, 50, 60, 72, 87, 105, 128, 156, 190,
232, 284, 347, 426, 522, 640]
The curve fitting is simple done by using
popt, pcov = curve_fit(func, x_data, y_data)
For the plot
plt.plot(xdata, func(xdata, *popt), 'g--', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.plot(x_data, y_data, 'ro')
plt.xlabel('Volume')
plt.ylabel('Costs')
plt.show()
A simple solution might just look like this:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import least_squares
def fit_function(x, a, b, c, d):
return a**2 + b**2 * x + c**2 * abs(x)**d
def residuals( params, xData, yData):
diff = [ fit_function(x, *params ) - y for x, y in zip( xData, yData ) ]
return diff
fit1 = least_squares( residuals, [ .1, .1, .1, .5 ], loss='soft_l1', args=( x1Data, y1Data ) )
print fit1.x
fit2 = least_squares( residuals, [ .1, .1, .1, .5 ], loss='soft_l1', args=( x2Data, y2Data ) )
print fit2.x
testX1 = np.linspace(0, 1.1 * max( x1Data ), 100 )
testX2 = np.linspace(0, 1.1 * max( x2Data ), 100 )
testY1 = [ fit_function( x, *( fit1.x ) ) for x in testX1 ]
testY2 = [ fit_function( x, *( fit2.x ) ) for x in testX2 ]
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
ax.scatter( x1Data, y1Data )
ax.scatter( x2Data, y2Data )
ax.plot( testX1, testY1 )
ax.plot( testX2, testY2 )
plt.show()
providing
>>[ 1.00232004e-01 -1.10838455e-04 2.50434266e-01 5.73214256e-01]
>>[ 1.00104293e-01 -2.57749592e-05 1.83726191e-01 5.55926678e-01]
and
It just takes the parameters as squares, therefore ensuring positive slope. Naturally, the fit becomes worse if following the decreasing points at the end of data set 1 is forbidden. Concerning this I'd say those are just statistical outliers. Therefore, I used least_squares, which can deal with this with a soft loss. See this doc for details. Depending on how the real data set is, I'd think about removing them. Finally, I'd expect that zero volume produces zero costs, so the constant term in the fit function doesn't seem to make sense.
So if the function is only of type a**2 * x + b**2 * sqrt(x) it look like:
where the green graph is the result of leastsq, i.e. without the f_scale option of least_squares.

out of stack space (infinite loop?) error while working with matplolib and Django

I am trying to show a graph which I am trying to plot in Matplotlib and then showing it with some hard coding in HTML template.But out of 3 attempts, it is working only once else it is throwing TCL Out of stack space error. Below is my coding.
def similar_images(request):
n_groups = 5
means_men = (20, 35, 30, 35, 27)
std_men = (2, 3, 4, 1, 2)
means_women = (25, 32, 34, 20, 25)
std_women = (3, 5, 2, 3, 3)
fig, ax = plt.subplots() # somwhere here it is throwing this error
index = np.arange(n_groups)
bar_width = 0.35
opacity = 0.4
error_config = {'ecolor': '0.3'}
rects1 = plt.bar(index, means_men, bar_width,
alpha=opacity,
color='b',
yerr=std_men,
error_kw=error_config,
label='Men')
rects2 = plt.bar(index + bar_width, means_women, bar_width,
alpha=opacity,
color='r',
yerr=std_women,
error_kw=error_config,
label='Women')
plt.xlabel('Shoe')
plt.ylabel('Week')
plt.title('Last Year sale details')
#plt.xticks(index + bar_width / 2, ('A', 'B', 'C', 'D', 'E'))
plt.legend()
plt.savefig('/graph.png')
plt.close()
return render(request,'sales/Details.html')
Please, can someone help me here?
Below is the error.
Exception Type: TclError at /sales/similar_images/
Exception Value: out of stack space (infinite loop?)

Single function to bubble sort 2 lists

Good evening. I have managed to bubble sort listOne. ListTwo will also need sorting. Is there a way to add listTwo into the bubble sort that I already have so that it gets sorted as well.
Or do I need to write another loop?
listOne = [3, 9, 2, 6, 1]
listTwo = [4, 8, 5, 7, 0]
def bubbleSort (inList):
moreSwaps = True
while (moreSwaps):
moreSwaps = False
for element in range(len(listOne)-1):
if listOne[element]> listOne[element+1]:
moreSwaps = True
temp = listOne[element]
listOne[element]=listOne[element+1]
listOne[element+1]= temp
return (inList)
print ("List One = ", listOne)
print ("List One Sorted = ", bubbleSort (listOne))
print ("List Two = ", listTwo)
print ("List Two Sorted = ", bubbleSort (listTwo))
I think you just need one method and then call the call it on the two list you can try this:
That is one method to do two jobs for you.
listOne = [3, 9, 2, 6, 1]
listTwo = [4, 8, 5, 7, 0]
def bubblesort(array):
for i in range(len(array)):
for j in range(len(array) - 1):
if array[j] > array[j + 1]:
swap = array[j]
array[j] = array[j + 1]
array[j + 1] = swap
print(array)
bubblesort(listOne)
bubblesort(listTwo)
[1, 2, 3, 6, 9]
[0, 4, 5, 7, 8]

Scatterplot legend and fill not working in Octave

I am using Octave.
My problem is this: I want to fill the bubbles of my scatter plot, as well as place a legend. But I get errors when I try to use 'filled', and no legend comes up when I use legend(...).
Part of my code looks like this:
%ALL SAMPLES, PHI(Signal) # THETA(Sample)=0
figure(5)
plot( Angles(:,1)([18:27]), ALL([18:27]), 10, [1 0 1]); %Magenta
hold on
scatter(Angles(:,1)([68:76]), ALL([68:76]), 10, [0 0 0]); %Black
scatter(Angles(:,1)([86:95]), ALL([86:95]), 10, [1 0 0]); %Red
scatter(Angles(:,1)([119:127]), ALL([119:127]), 10, [0 1 0]); %Green
scatter(Angles(:,1)([133:141]), ALL([133:141]), 10, [0 0 1]); %Blue
hold off
xlabel('Signal PMT angle (Sample angle at 0)');
ylabel('Normalized (signal/monitor) intensity');
legend('Control', 'Control', '1+2','Virgin','Cycle #1', 'Location','NorthEast');
title('Plot of All Samples, "-int Intensity"')
I know it should beplot( Angles(:,1)([18:27]), ALL([18:27]), 10, [1 0 1], 'filled');, but I receive errors when I do that. Also, a legend never seems to show up.
Apparently there is a problem with using legend with scatter in Octave. Based on this post:
http://octave.1599824.n4.nabble.com/Legend-in-scatter-plot-td3568032.html
the trick is to use the plot function to make scatter plot. I wrote the following function for plotting a bunch of scatter plots on the same axis.
This function takes in a bunch of cell arrays of the same length. Each element of the cell array corresponds to a separate series. The function returns a cell array of the same length containing the handle associated with each plot. The arguments of the function are explained below:
x_vals: a cell array of arrays of doubles corresponding to x values.
y_vals: a cell array of arrays of doubles corresponding to y values.
sizes: a cell array of doubles representing the size of the markers.
colors: a cell array of double arrays of length 3, representing [R, G, B] color values of the markers.
styles: a cell array of strings representing the shape of the markers.
function [handles] = scatter_series_set(x_vals, y_vals, sizes, colors, styles)
N = length(x_vals);
if ( (~ ( N == length(y_vals))) || (~ ( N == length(sizes))) || ...
(~ ( N == length(colors))) || (~ ( N == length(styles))) )
error('scatter_series_set: all arguments must be cell arrays of the same length');
end
%plot the first series
handles = cell([N, 1]);
handles{1} = plot(x_vals{1}, y_vals{1});
set(handles{1}, 'linestyle', 'none');
set(handles{1}, 'marker', styles{1});
set(handles{1}, 'markersize', sizes{1});
set(handles{1}, 'color', colors{1});
%plot additional series if present
if N > 1
hold on;
for ind = 2:N
handles{ind} = plot(x_vals{ind}, y_vals{ind});
set(handles{ind}, 'linestyle', 'none');
set(handles{ind}, 'marker', styles{ind});
set(handles{ind}, 'markersize', sizes{ind});
set(handles{ind}, 'color', colors{ind});
end
hold off;
end
end
The following example demonstrates how to use this function.
x1 = 0:(2*pi/100):(2*pi);
x2 = 2*x1;
y1 = sin(x1);
y2 = cos(x1);
y3 = sin(x2);
y4 = cos(x2);
names = {'a', 'b', 'c', 'd'};
x_vals = {x1, x1, x1, x1};
y_vals = {y1, y2, y3, y4};
sizes = {10, 10, 10, 10};
colors = {[1, 0, 0], [0, 0, 1], [0, 0, 0], [0.7071, 0, 0.7071]};
styles = {'^', 's', 'x', '+'}
scatter_series_set(x_vals, y_vals, sizes, colors, styles);
legend(names, 'location', 'southeast');
The example code produces the following plot:
The following works for me:
n = 100;
x = randn(n, 1);
y = randn(n, 1);
S = rand(n, 1)*20;
hold on
scatter(x(1:50), y(1:50), S(1:50), "red", "filled")
scatter(x(51:100), y(51:100), S(51:100), "green", "filled")
hold off
print('-depsc', 'bubbleplot.eps');
However, I'm not able to add a legend, and I didn't find any bug report or indication of a missing functionality for this. So, as an alternative, I would suggest adding marker and text to your plot.