In [451]:
%pylab inline

import csv
import pandas as pd

from scipy.interpolate import SmoothBivariateSpline
from scipy.optimize import minimize
from scipy.stats import shapiro

from mpl_toolkits.mplot3d import Axes3D

from threshold_functions import *


Populating the interactive namespace from numpy and matplotlib
WARNING: pylab import has clobbered these variables: ['f']
`%matplotlib` prevents importing * from pylab and numpy

In [452]:
pylab.rcParams['savefig.dpi'] = 130

In [453]:
# Define thresholds
giveThreshold = 0.5
gapThreshold = 130

In [454]:
with open('cutout_factors','r') as f:
    
    loaded_factor = eval(f.read())
    
dictArray = array(list(loaded_factor.items()),float)
cutoutRef = dictArray[:,0].astype(int)
factor = dictArray[:,1]


with open('circle_cutout_factors','r') as f:
    
    loaded_circle_factor = eval(f.read())
    
circleDictArray = array(list(loaded_circle_factor.items()),float)
circleDiameter = circleDictArray[:,0]
circleFactor = circleDictArray[:,1]

factor = append(factor,circleFactor)


with open('custom_cutout_factors','r') as f:
    
    loaded_custom_factor = eval(f.read())

customDimensionsDict = {'5x13':[5,13],
                   '5x10':[5,10],
                   '5x8':[5,8],
                   '4x13':[4,13],
                   '4x10':[4,10],
                   '4x8':[4,8],
                   '4x6.5':[4,6.5],
                   '3x13':[3,13],
                   '3x9':[3,9],
                   '3x6.5':[3,6.5],
                   '3x5':[3,5]}

customDataLabelList = list(customDimensionsDict.keys())

custom_factors = [loaded_custom_factor[x] for x in customDataLabelList]
custom_widths = [customDimensionsDict[x][0] for x in customDataLabelList]
custom_lengths = [customDimensionsDict[x][1] for x in customDataLabelList]


factor = append(factor,custom_factors)

In [455]:
# loaded_factor.items()

In [456]:
cutout_dimensions = pd.DataFrame.from_csv('../data/cutout_dimensions.csv')

width = cutout_dimensions['width'].values[cutoutRef]
length = cutout_dimensions['length'].values[cutoutRef]

weight = concatenate((ones(shape(width)), 1*ones(shape(circleDiameter)), ones(shape(custom_widths))))


width = append(width,circleDiameter)
length = append(length,circleDiameter)

nanFill = empty(shape(circleDiameter))
nanFill.fill(nan)

cutoutRef = append(cutoutRef,nanFill)


width = append(width,custom_widths)
length = append(length,custom_lengths)

nanFill = empty(shape(custom_widths))
nanFill.fill(nan)

cutoutRef = append(cutoutRef,nanFill)



# editRef = cutoutRef == 14
# width[editRef] = 4.3
# length[editRef] = 4.6

ratio = width / length

In [457]:
shuffleArray = arange(len(width),dtype=int)
shuffle(shuffleArray)

numToKeep = 11
toKeepRef = zeros(len(width))

toKeepRef[shuffleArray[0:numToKeep]] = 1
toKeepRef = toKeepRef.astype(bool)

In [497]:
arrayPicker = array([29,28,27,26,34,40,41,0,1,2,4,5,7,37,32],dtype=int) #,30,25,24

toKeepRef = zeros(len(width))
toKeepRef[arrayPicker] = 1
toKeepRef = toKeepRef.astype(bool)


print(len(arrayPicker))

scatter(width[~toKeepRef],ratio[~toKeepRef],c="grey")
scatter(width[toKeepRef],ratio[toKeepRef],c="red")
title('Data this time round')
xlabel('Width (cm)')
ylabel('Ratio')


15
Out[497]:
<matplotlib.text.Text at 0x237297b8>

In [498]:
# cutoutRef,width, length, factor, ratio

In [498]:


In [499]:
# Spline fitting

widthMirrored = np.append(width[toKeepRef],width[toKeepRef])
ratioLogMirrored = np.log2(np.append(width[toKeepRef]/length[toKeepRef],length[toKeepRef]/width[toKeepRef]))
factorMirrored = np.append(factor[toKeepRef],factor[toKeepRef])
weightMirrored = append(weight[toKeepRef],weight[toKeepRef])

splineFit = SmoothBivariateSpline(widthMirrored,ratioLogMirrored,factorMirrored,w=weightMirrored,s=len(width[toKeepRef]))

In [500]:
# Create surface mesh
xVec2 = linspace(width.min(),width.max(),100)
yVec2 = linspace(ratio.min(),ratio.max(),100)
xMesh2, yMesh2 = meshgrid(xVec2, yVec2)

gapMesh2 = angle_gap(xMesh2,log2(yMesh2),widthMirrored,ratioLogMirrored,1,2)
giveMesh2 = fit_give(xMesh2,log2(yMesh2),widthMirrored,ratioLogMirrored,factorMirrored,s=len(width))

zMesh2 = splineFit.ev(xMesh2, log2(yMesh2))

ref2 = (gapMesh2>gapThreshold) | (giveMesh2>giveThreshold)
zMesh2[ref2] = nan

In [516]:
fig = plt.figure()
ax = fig.add_subplot(111)

cf = ax.contourf(xMesh2,yMesh2,giveMesh2,60)
colorbar(cf, label='Fit give')

ax.contour(xMesh2,yMesh2,giveMesh2,levels=[giveThreshold],colors='k')

ax.scatter(width[~toKeepRef],ratio[~toKeepRef],c="grey")
ax.scatter(width[toKeepRef],ratio[toKeepRef],c="red")

ax.set_xlabel('Width')
ax.set_ylabel('Ratio')

ax.set_title('Contour plot of the fit give')


Out[516]:
<matplotlib.text.Text at 0x244684a8>

In [519]:
fig = plt.figure()

ax = fig.add_subplot(111)

cf = ax.contourf(xMesh2,yMesh2,gapMesh2,60)
colorbar(cf, label='Angle gap')

ax.contour(xMesh2,yMesh2,gapMesh2,levels=[gapThreshold],colors='k')

ax.scatter(width[~toKeepRef],ratio[~toKeepRef],c="grey")
ax.scatter(width[toKeepRef],ratio[toKeepRef],c="red")

ax.set_xlabel('Width')
ax.set_ylabel('Ratio')

ax.set_title('Contour plot of the angle gap')


Out[519]:
<matplotlib.text.Text at 0x270011d0>

In [502]:
# Plot the fit
fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')

bot = np.amin(factor) - 0.04 * np.ptp(factor)
top = np.amax(factor) + 0.04 * np.ptp(factor)

ax.contour(xMesh2,yMesh2,gapMesh2, offset=bot, levels=[gapThreshold], colors='r',alpha=0.3)
ax.contour(xMesh2,yMesh2,giveMesh2, offset=bot, levels=[giveThreshold], colors='g',alpha=0.3)

proxyGap, = ax.plot([width.min(),width.min()],[ratio.min(),ratio.min()],[bot,bot],'r-',alpha=0.3)
proxyGive, = ax.plot([width.min(),width.min()],[ratio.min(),ratio.min()],[bot,bot],'g-',alpha=0.3)

ax.plot_surface(xMesh2,yMesh2,zMesh2,alpha=0.3,rstride=4,cstride=4)
ax.scatter(width[~toKeepRef],ratio[~toKeepRef],factor[~toKeepRef],c="grey")
ax.scatter(width[toKeepRef],ratio[toKeepRef],factor[toKeepRef],c="red")

ax.set_title('Fit displayed against width and aspect ratio')
ax.set_xlabel('Width')
ax.set_ylabel('Ratio')
ax.set_zlabel('Factor')
legend([proxyGap,proxyGive],['Gap threshold', 'Give threshold'],loc=7,prop={'size':8})

right = ratio.min()-0.01*ratio.ptp()
ax.set_ylim(right,1)
ax.set_zlim(bot,top)
ax.view_init(elev=10, azim=-80)



In [503]:
# Remove data and predict
predictedFactor = zeros(shape(width))
predictionAngleGap = zeros(shape(width))
predictionFitGive = zeros(shape(width))

for i in range(len(width)):
    
    x = width[i]
    y = log2(width[i]/length[i])
    
    adjToKeepRef = toKeepRef.copy()
    adjToKeepRef[i] = 0
    
    adjWidth = width[adjToKeepRef]
    adjLength = length[adjToKeepRef]
    adjFactor = factor[adjToKeepRef]
    adjWeight = weight[adjToKeepRef]
    
    adjWidthMirrored = np.append(adjWidth,adjWidth)
    adjRatioLogMirrored = np.log2(np.append(adjWidth/adjLength,adjLength/adjWidth))
    adjFactorMirrored = np.append(adjFactor,adjFactor)
    adjWeightMirrored = append(adjWeight,adjWeight)
    
    adjSplineFit = SmoothBivariateSpline(adjWidthMirrored,adjRatioLogMirrored,adjFactorMirrored,w=adjWeightMirrored,s=len(adjWidth))
    
    predictedFactor[i] = adjSplineFit.ev(x,y)
    predictionAngleGap[i] = angle_gap(x,y,adjWidthMirrored,adjRatioLogMirrored,1,2)
    predictionFitGive[i] = fit_give(x,y,adjWidthMirrored,adjRatioLogMirrored,adjFactorMirrored,s=len(adjWidth))
    
difference = factor - predictedFactor
withinThresholds = ((predictionAngleGap<gapThreshold) & 
                    (predictionFitGive<giveThreshold)
                    )

In [504]:
# Display table
df = pd.DataFrame(transpose([cutoutRef,width, length, factor, predictedFactor, difference,
                             predictionAngleGap, predictionFitGive, withinThresholds]))
df.columns = ['Reference','width', 'length', 'factor', 'Predicted Factor', 'Difference',
              'Angle Gap', 'Fit Give', 'Within thresholds']

# df.to_csv(path_or_buf = "cutoutdata.csv", index=False)

df


Out[504]:
Reference width length factor Predicted Factor Difference Angle Gap Fit Give Within thresholds
0 43 6.103849 7.736637 1.007783 1.007470 0.000312 68.026681 0.761532 0
1 3 4.536055 6.035738 1.032704 1.030591 0.002114 56.623353 0.311813 1
2 6 7.245140 10.062915 1.001302 0.995264 0.006038 168.643000 0.572114 0
3 82 6.276570 7.584045 1.000867 1.005903 -0.005036 63.930426 0.341334 1
4 112 3.510689 4.141420 1.053904 1.057997 -0.004094 123.077411 0.172857 1
5 18 7.637566 9.560354 0.998054 0.995779 0.002275 165.402156 0.612295 0
6 20 4.265897 5.041729 1.037967 1.037890 0.000076 48.591868 0.187951 1
7 16 6.176973 10.235482 0.999567 1.008892 -0.009325 156.623280 0.686999 0
8 109 6.478522 7.636965 1.006979 1.004010 0.002969 61.011024 0.337102 1
9 106 6.042542 9.643383 1.000871 1.006865 -0.005994 74.141810 0.315942 1
10 41 6.882961 10.087318 0.994829 1.000726 -0.005898 160.000991 0.350146 0
11 58 5.968616 7.249113 1.008999 1.009224 -0.000225 28.979679 0.313580 1
12 73 7.253007 9.401196 0.995472 0.998468 -0.002996 111.952585 0.278698 1
13 32 7.728437 10.890306 0.993330 0.997067 -0.003736 183.630498 0.799093 0
14 22 5.216353 9.919577 1.011713 1.014515 -0.002802 129.984147 0.341129 1
15 70 7.461885 8.181920 0.997190 0.996957 0.000234 85.806264 0.325287 1
16 19 5.804896 10.176211 1.001089 1.008374 -0.007285 148.294008 0.331979 0
17 34 7.095174 9.471365 0.993330 0.999398 -0.006068 80.262603 0.260551 1
18 57 3.541777 4.655761 1.059704 1.055440 0.004264 125.010990 0.179126 1
19 38 4.571007 5.636698 1.027190 1.031145 -0.003955 47.829445 0.208649 1
20 14 4.507535 4.917415 1.043027 1.032995 0.010032 36.416166 0.172072 1
21 104 5.578054 8.115864 1.006601 1.012989 -0.006388 62.055394 0.369301 1
22 83 5.676411 7.903129 1.010552 1.012064 -0.001512 55.265607 0.366275 1
23 33 5.933829 6.141369 1.006789 1.009970 -0.003181 35.866169 0.164443 1
24 NaN 4.000000 4.000000 1.045826 1.044524 0.001302 54.104885 0.146055 1
25 NaN 6.000000 6.000000 1.014436 1.009191 0.005245 36.696463 0.161597 1
26 NaN 3.000000 3.000000 1.075771 1.069827 0.005944 180.000000 0.325266 0
27 NaN 5.000000 5.000000 1.030396 1.019928 0.010468 29.663569 0.221125 1
28 NaN 7.000000 7.000000 0.996776 1.007124 -0.010348 55.242860 0.547565 0
29 NaN 9.000000 9.000000 0.991661 0.997382 -0.005721 284.597143 0.948886 0
30 NaN 8.000000 8.000000 0.993360 0.994413 -0.001052 111.527414 0.267499 1
31 NaN 5.000000 10.000000 1.012277 1.016869 -0.004591 123.184512 0.347181 1
32 NaN 4.000000 13.000000 1.024896 1.015944 0.008952 172.746432 0.980681 0
33 NaN 3.000000 9.000000 1.053516 1.059417 -0.005901 180.000000 0.451306 0
34 NaN 3.000000 13.000000 1.049271 1.041235 0.008035 321.207364 0.999883 0
35 NaN 4.000000 6.500000 1.040668 1.040999 -0.000332 70.094205 0.291907 1
36 NaN 3.000000 6.500000 1.054423 1.066143 -0.011720 180.000000 0.477354 0
37 NaN 4.000000 8.000000 1.030055 1.039429 -0.009374 109.183310 0.601140 0
38 NaN 4.000000 10.000000 1.029933 1.031969 -0.002036 124.965085 0.316948 1
39 NaN 5.000000 8.000000 1.017153 1.020569 -0.003416 83.056781 0.338863 1
40 NaN 5.000000 13.000000 1.013374 0.994784 0.018590 178.083100 0.983599 0
41 NaN 3.000000 5.000000 1.069714 1.069956 -0.000242 180.000000 0.948987 0

In [505]:
print("There are", sum(withinThresholds), "points within give and gap thresholds."+
      "\nThe standard deviation of the prediction differences for these is", std(difference[withinThresholds]))


There are 25 points within give and gap thresholds.
The standard deviation of the prediction differences for these is 0.0044637099073

In [506]:
# Histogram
fig = plt.figure()
ax = fig.add_subplot(111)

n, bins, patches = hist(difference[withinThresholds])

setp(patches, 'facecolor', 'g', 'alpha', 0.5)
ax.set_xlabel('Prediction differences')
ax.set_ylabel('Frequency')
ax.set_title('Histogram of prediction differences')


Out[506]:
<matplotlib.text.Text at 0x2435e128>

In [507]:
W, pvalue = shapiro(difference[withinThresholds])
pvalue


Out[507]:
0.02717641554772854

In [508]:
# Visual representation of differences
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(xMesh2,yMesh2,zMesh2,alpha=0.3,rstride=4,cstride=4)

diffColour = copy(difference)
diffColour[~withinThresholds] = nan

colourRange = nanmax(abs(diffColour))

sc = ax.scatter(width,ratio,factor,c=diffColour, vmin=-colourRange, vmax=colourRange)
colorbar(sc)

ax.set_title('Differences')
ax.set_xlabel('Width')
ax.set_ylabel('Ratio')
ax.set_zlabel('Factor')

ax.set_ylim(right,1)
ax.set_zlim(bot,top)

ax.view_init(elev=10, azim=-80)



In [509]:
diffTest = abs(difference)
diffTest[~withinThresholds] = 0

testRef = argmax(diffTest)
cutoutRef[testRef]


Out[509]:
nan

In [510]:
factor[testRef]


Out[510]:
1.0303960695616821

In [511]:
scatter(width,ratio)
scatter(width[testRef],ratio[testRef],c='red')


Out[511]:
<matplotlib.collections.PathCollection at 0x23ab7e10>

In [512]:
def to_minimise(cut_increase,ref):
    
    test_width = width[ref] + cut_increase
    test_length = length[ref] + cut_increase
    test_ratio = test_width / test_length
    
    return (factor[ref] - splineFit.ev(test_width,log2(test_ratio)))**2

In [513]:
output = minimize(to_minimise,0,args=(testRef,))
output


Out[513]:
     njev: 17
      fun: 2.7642849738768614e-09
  message: 'Optimization terminated successfully.'
     nfev: 51
 hess_inv: array([[ 1368.01932814]])
      jac: array([  2.08018892e-06])
  success: True
   status: 0
        x: array([-0.35580746])

In [514]:
# scatter(width,ratio)

In [150]:


In [ ]: