Coverage for src/thunderfish/fishshapes.py: 99%

307 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-16 22:05 +0000

1"""Manipulate and plot fish outlines. 

2 

3## Fish shapes 

4 

5Fish shapes are dictionaries with the keys 'body', 'fin0', 'fin1' ..., 

6and 'eye'. The values are 2D arrays with x-y coordinates (first 

7dimension is points, second dimension coordinates) of the respective 

8pathes. 

9 

10All fish shapes of this module are accessible via these dictionaries: 

11 

12- `fish_shapes`: dictionary holding all electric fish shapes. 

13- `fish_top_shapes`: dictionary holding electric fish shapes viewed from top. 

14- `fish_side_shapes`: dictionary holding electric fish shapes viewed from the side. 

15 

16These are the shapes of various fish species: 

17 

18- `Alepto_top`: *Apteronotus leptorhynchus* viewed from top. 

19- `Alepto_male_side`: Male *Apteronotus leptorhynchus* viewed from the side. 

20- `Eigenmannia_top`: *Eigenmannia virescens* viewed from top. 

21- `Eigenmannia_side`: *Eigenmannia virescens* viewed from the side. 

22- `Gpetersii_top`: *Ganthonemus petersii* viewed from top. 

23- `Gpetersii_side`: *Ganthonemus petersii* viewed from the side. 

24 

25Helper function for selecting a particular fish shape: 

26 

27- `fish_shape()`: get a dictinary containing shapes of a fish. 

28 

29## Plotting 

30 

31- `plot_fish()`: plot body, fins and eye of an electric fish. 

32- `plot_object()`: plot circular object. 

33- `plot_fishfinder()`: plot a fishfinder with electrodes and wires. 

34- `plot_pathes()`: plot pathes. 

35 

36## Fish surface and normals from shapes 

37 

38- `fish_surface()`: generate meshgrid of one side of the fish from shape. 

39- `surface_normals()`: normal vectors on a surface. 

40 

41## General path manipulations 

42 

43You may use these functions to extract and fine tune pathes from SVG 

44files in order to assemble fish shapes for this module. See 

45`export_fish_demo()` for a use case. 

46 

47- `extract_path()`: convert SVG pathes to numpy arrays with path coordinates. 

48- `bbox_pathes()`: common bounding box of pathes. 

49- `translate_pathes()`: translate pathes in place. 

50- `center_pathes()`: translate pathes to their common origin in place. 

51- `rotate_pathes()`: rotate pathes in place. 

52- `flipy_pathes()`: flip pathes in y-direction in place. 

53- `flipx_pathes()`: flip pathes in x-direction in place. 

54- `export_path()`: print coordinates of path for import as numpy array. 

55- `mirror_path()`: complete path of half a fish outline by appending the mirrored path. 

56- `normalize_path()`: normalize fish outline to unit length. 

57- `bend_path()`: bend and scale a path. 

58 

59## Exporting fish outlines from pathes 

60 

61- `export_fish()`: serialize coordinates of fish outlines as a dictionary. 

62- `export_fish_demo()`: code demonstrating how to export fish outlines from SVG file. 

63 

64""" 

65 

66import numpy as np 

67import matplotlib as mpl 

68import matplotlib.pyplot as plt 

69from matplotlib.path import Path 

70from matplotlib.patches import PathPatch, Circle, Rectangle 

71import matplotlib.transforms as mpt 

72 

73 

74Alepto_top = dict(body=np.array([ 

75 [-5.00000000e-01, 0.00000000e+00], [-4.99802704e-01, 1.23222860e-03], 

76 [-4.95374557e-01, 2.57983066e-03], [-4.84420392e-01, 3.29085947e-03], 

77 [-4.72487909e-01, 4.03497963e-03], [-4.13995354e-01, 4.39637211e-03], 

78 [-3.90529212e-01, 5.14049228e-03], [-3.67089631e-01, 5.88461244e-03], 

79 [-3.43596916e-01, 6.65006783e-03], [-3.20104187e-01, 7.39418800e-03], 

80 [-2.97063253e-01, 8.11708180e-03], [-2.79461930e-01, 8.49142780e-03], 

81 [-2.61664711e-01, 9.24382081e-03], [-2.38198570e-01, 1.03918950e-02], 

82 [-2.14732428e-01, 1.14974077e-02], [-1.91239699e-01, 1.26242555e-02], 

83 [-1.67773558e-01, 1.37511034e-02], [-1.44307403e-01, 1.52605701e-02], 

84 [-1.09307508e-01, 1.71314946e-02], [-8.58413531e-02, 1.86197349e-02], 

85 [-6.23486380e-02, 2.01079753e-02], [-3.88824966e-02, 2.12348231e-02], 

86 [-1.54429155e-02, 2.19789433e-02], [1.95835670e-02, 2.31057367e-02], 

87 [4.30231346e-02, 2.38498569e-02], [6.65424230e-02, 2.49767047e-02], 

88 [8.99820050e-02, 2.57421601e-02], [1.13448146e-01, 2.64862803e-02], 

89 [1.36914287e-01, 2.91013032e-02], [1.60380442e-01, 3.28431304e-02], 

90 [1.83873157e-01, 3.43101008e-02], [2.06914105e-01, 3.54369487e-02], 

91 [2.18819919e-01, 3.58196764e-02], [2.42339207e-01, 3.65850229e-02], 

92 [2.72903364e-01, 3.57933339e-02], [2.75411585e-01, 3.56061065e-02], 

93 [2.74126982e-01, 3.73081344e-02], [2.60251756e-01, 4.14908387e-02], 

94 [2.47930096e-01, 4.96419915e-02], [2.39119358e-01, 6.08413919e-02], 

95 [2.39547832e-01, 7.56059835e-02], [2.44279733e-01, 7.95534778e-02], 

96 [2.54298155e-01, 7.66782524e-02], [2.69627591e-01, 6.28724285e-02], 

97 [2.82177993e-01, 4.80249888e-02], [2.88316671e-01, 3.79294791e-02], 

98 [2.89271585e-01, 3.54368942e-02], [2.92213886e-01, 3.54205663e-02], 

99 [3.01203973e-01, 3.58192954e-02], [3.12737740e-01, 4.10493520e-02], 

100 [3.24670128e-01, 3.99438067e-02], [3.36177308e-01, 3.88170133e-02], 

101 [3.48109696e-01, 3.76902090e-02], [3.71177217e-01, 3.54366112e-02], 

102 [3.94643358e-01, 3.24601523e-02], [4.18136073e-01, 2.91010093e-02], 

103 [4.41602228e-01, 2.61033022e-02], [4.65041796e-01, 2.27229002e-02], 

104 [4.77000757e-01, 2.01078773e-02], [4.88938465e-01, 1.57516176e-02], 

105 [4.97051671e-01, 9.88149348e-03], [5.00000000e-01, 4.58499286e-03], 

106 [5.00000000e-01, -4.58499286e-03], [4.97051671e-01, -9.88149348e-03], 

107 [4.88938465e-01, -1.57516176e-02], [4.77000757e-01, -2.01078773e-02], 

108 [4.65041796e-01, -2.27229002e-02], [4.41602228e-01, -2.61033022e-02], 

109 [4.18136073e-01, -2.91010093e-02], [3.94643358e-01, -3.24601523e-02], 

110 [3.71177217e-01, -3.54366112e-02], [3.48109696e-01, -3.76902090e-02], 

111 [3.36177308e-01, -3.88170133e-02], [3.24670128e-01, -3.99438067e-02], 

112 [3.12737740e-01, -4.10493520e-02], [3.01203973e-01, -3.58192954e-02], 

113 [2.92213886e-01, -3.54205663e-02], [2.89271585e-01, -3.54368942e-02], 

114 [2.88316671e-01, -3.79294791e-02], [2.82177993e-01, -4.80249888e-02], 

115 [2.69627591e-01, -6.28724285e-02], [2.54298155e-01, -7.66782524e-02], 

116 [2.44279733e-01, -7.95534778e-02], [2.39547832e-01, -7.56059835e-02], 

117 [2.39119358e-01, -6.08413919e-02], [2.47930096e-01, -4.96419915e-02], 

118 [2.60251756e-01, -4.14908387e-02], [2.74126982e-01, -3.73081344e-02], 

119 [2.75411585e-01, -3.56061065e-02], [2.72903364e-01, -3.57933339e-02], 

120 [2.42339207e-01, -3.65850229e-02], [2.18819919e-01, -3.58196764e-02], 

121 [2.06914105e-01, -3.54369487e-02], [1.83873157e-01, -3.43101008e-02], 

122 [1.60380442e-01, -3.28431304e-02], [1.36914287e-01, -2.91013032e-02], 

123 [1.13448146e-01, -2.64862803e-02], [8.99820050e-02, -2.57421601e-02], 

124 [6.65424230e-02, -2.49767047e-02], [4.30231346e-02, -2.38498569e-02], 

125 [1.95835670e-02, -2.31057367e-02], [-1.54429155e-02, -2.19789433e-02], 

126 [-3.88824966e-02, -2.12348231e-02], [-6.23486380e-02, -2.01079753e-02], 

127 [-8.58413531e-02, -1.86197349e-02], [-1.09307508e-01, -1.71314946e-02], 

128 [-1.44307403e-01, -1.52605701e-02], [-1.67773558e-01, -1.37511034e-02], 

129 [-1.91239699e-01, -1.26242555e-02], [-2.14732428e-01, -1.14974077e-02], 

130 [-2.38198570e-01, -1.03918950e-02], [-2.61664711e-01, -9.24382081e-03], 

131 [-2.79461930e-01, -8.49142780e-03], [-2.97063253e-01, -8.11708180e-03], 

132 [-3.20104187e-01, -7.39418800e-03], [-3.43596916e-01, -6.65006783e-03], 

133 [-3.67089631e-01, -5.88461244e-03], [-3.90529212e-01, -5.14049228e-03], 

134 [-4.13995354e-01, -4.39637211e-03], [-4.72487909e-01, -4.03497963e-03], 

135 [-4.84420392e-01, -3.29085947e-03], [-4.95374557e-01, -2.57983066e-03], 

136 [-4.99802704e-01, -1.23222860e-03], [-5.00000000e-01, -0.00000000e+00],])) 

137"""Outline of an *Apteronotus leptorhynchus* viewed from top, modified from Krahe 2004.""" 

138 

139Alepto_male_side = dict(body=np.array([ 

140 [2.80332097e-01, 5.51361973e-02], [2.41127905e-01, 5.93460338e-02], 

141 [1.91463866e-01, 6.22667811e-02], [1.37379023e-01, 6.17716006e-02], 

142 [6.91234340e-02, 5.72953633e-02], [-1.36051588e-02, 4.74838393e-02], 

143 [-7.55221954e-02, 3.64211032e-02], [-1.60157310e-01, 2.45651115e-02], 

144 [-2.32035003e-01, 1.55421483e-02], [-2.99079447e-01, 9.70960800e-03], 

145 [-3.62251791e-01, 6.27265707e-03], [-4.20527920e-01, 4.22449025e-03], 

146 [-4.72735573e-01, 5.39606712e-03], [-4.80154179e-01, 5.86398206e-03], 

147 [-4.92605065e-01, 1.01411700e-02], [-4.97402289e-01, 5.91543079e-03], 

148 [-5.00000000e-01, -2.84973497e-03], [-4.97832769e-01, -1.17981289e-02], 

149 [-4.93106950e-01, -1.43380199e-02], [-4.81164618e-01, -8.19215843e-03], 

150 [-4.72578673e-01, -6.17623988e-03], [-4.45390092e-01, -5.96123217e-03], 

151 [-3.74805165e-01, -9.05994885e-03], [-3.33716813e-01, -1.08317142e-02], 

152 [-3.08099380e-01, -1.15017063e-02], [-2.82451613e-01, -1.30396176e-02], 

153 [-2.34498580e-01, -2.21834040e-02], [-1.86892658e-01, -3.26728000e-02], 

154 [-1.08738732e-01, -4.99024273e-02], [-3.50753879e-02, -5.94218882e-02], 

155 [3.28767168e-02, -6.58397526e-02], [1.25319086e-01, -7.21513968e-02], 

156 [1.99523049e-01, -7.99740378e-02], [2.37035792e-01, -8.44828747e-02], 

157 [2.74475366e-01, -8.68964223e-02], [3.12742824e-01, -8.34038539e-02], 

158 [3.36340505e-01, -7.82231053e-02], [3.55492327e-01, -7.21451373e-02], 

159 [3.74670470e-01, -6.45564453e-02], [3.82920881e-01, -6.06824741e-02], 

160 [3.84828678e-01, -5.92550189e-02], [3.86562866e-01, -5.99353293e-02], 

161 [3.90753372e-01, -6.01589140e-02], [4.03494946e-01, -5.90960625e-02], 

162 [4.38474761e-01, -6.13270959e-02], [4.61389913e-01, -6.47960654e-02], 

163 [4.77010163e-01, -6.86433853e-02], [4.84437594e-01, -6.89404377e-02], 

164 [4.90842798e-01, -6.82840746e-02], [4.94567181e-01, -6.58050993e-02], 

165 [4.95443985e-01, -6.30972916e-02], [4.94497789e-01, -6.10849673e-02], 

166 [4.91729699e-01, -6.00016418e-02], [4.84298546e-01, -5.78808424e-02], 

167 [4.93112897e-01, -5.45550751e-02], [4.97742360e-01, -5.12667865e-02], 

168 [5.00000000e-01, -4.73196051e-02], [4.99521047e-01, -4.36153642e-02], 

169 [4.96159278e-01, -3.87756472e-02], [4.86402575e-01, -3.18513601e-02], 

170 [4.67134496e-01, -2.06920393e-02], [4.39218141e-01, -5.92866768e-03], 

171 [4.25010402e-01, 4.45359743e-03], [4.14788070e-01, 1.39860522e-02], 

172 [3.93656086e-01, 2.44160739e-02], [3.75679976e-01, 2.94323719e-02], 

173 [3.61404254e-01, 3.69002336e-02], [3.37900061e-01, 4.40458301e-02], 

174 [3.11463577e-01, 4.97553861e-02],]), 

175 fin0=np.array([ 

176 [3.29593304e-01, -7.95912942e-02], [3.27561074e-01, -8.48367727e-02], 

177 [3.08709726e-01, -9.90609655e-02], [2.80934315e-01, -1.08062137e-01], 

178 [2.58017473e-01, -1.12878542e-01], [2.35142157e-01, -1.14467112e-01], 

179 [2.18081531e-01, -1.12354592e-01], [1.98185626e-01, -1.10721292e-01], 

180 [1.78099090e-01, -1.13640193e-01], [1.59752865e-01, -1.18762090e-01], 

181 [1.40752841e-01, -1.20266781e-01], [1.27904629e-01, -1.17712356e-01], 

182 [1.19134213e-01, -1.12284346e-01], [1.09580014e-01, -1.04436264e-01], 

183 [8.20184710e-02, -9.60992771e-02], [5.05598670e-02, -9.57289587e-02], 

184 [2.74790284e-02, -1.04021601e-01], [3.92704920e-03, -1.08834461e-01], 

185 [-3.12710137e-02, -1.08965162e-01], [-5.88865488e-02, -1.03820945e-01], 

186 [-7.82549598e-02, -9.45428978e-02], [-9.94601687e-02, -8.20174601e-02], 

187 [-1.29941640e-01, -7.01658118e-02], [-1.58259295e-01, -6.73695625e-02], 

188 [-1.86001442e-01, -7.01570717e-02], [-2.14339679e-01, -6.79007296e-02], 

189 [-2.38708971e-01, -5.78982409e-02], [-2.55168178e-01, -4.41230328e-02], 

190 [-2.71293058e-01, -3.28785160e-02], [-2.88416341e-01, -2.86291802e-02], 

191 [-3.06103856e-01, -2.82461534e-02], [-3.22345146e-01, -2.47128040e-02], 

192 [-3.38333410e-01, -1.44124470e-02], [-3.43264223e-01, -1.03691894e-02], 

193 [-3.08609907e-01, -1.12571357e-02], [-2.86088545e-01, -1.25633719e-02], 

194 [-2.59977440e-01, -1.65414204e-02], [-2.16119429e-01, -2.64072955e-02], 

195 [-1.68443229e-01, -3.68996138e-02], [-1.12717944e-01, -4.88585839e-02], 

196 [-7.07908982e-02, -5.51259999e-02], [-1.80906639e-02, -6.16068166e-02], 

197 [2.75299392e-02, -6.53080983e-02], [7.71390030e-02, -6.85205021e-02], 

198 [1.21071140e-01, -7.25104674e-02], [1.78723549e-01, -7.85286909e-02], 

199 [2.32100395e-01, -8.40268652e-02], [2.74938812e-01, -8.74456073e-02], 

200 [3.10041908e-01, -8.43007220e-02],]), 

201 eye=np.array([0.4, 0.0, 0.01])) 

202"""Outline of an *Apteronotus leptorhynchus* male viewed from the side.""" 

203 

204Eigenmannia_top = dict(body=np.array([ 

205 [-5.00000000e-01, 0.00000000e+00], [-4.84515329e-01, 4.41536208e-03], 

206 [-4.76913801e-01, 5.34924846e-03], [-3.94680346e-01, 8.25734868e-03], 

207 [-2.74106007e-01, 8.94059314e-03], [-1.35145770e-01, 1.09559947e-02], 

208 [2.36080412e-02, 1.40941342e-02], [1.36968804e-01, 1.51550643e-02], 

209 [2.15041020e-01, 1.96734219e-02], [2.83582110e-01, 2.36895289e-02], 

210 [3.20834553e-01, 2.63067663e-02], [3.46646908e-01, 2.77590937e-02], 

211 [3.68462758e-01, 2.97229886e-02], [3.62525174e-01, 3.12766064e-02], 

212 [3.57215426e-01, 3.25163153e-02], [3.51347983e-01, 3.44809486e-02], 

213 [3.46108357e-01, 3.83290703e-02], [3.44207747e-01, 4.53621620e-02], 

214 [3.46387987e-01, 5.39648157e-02], [3.54784122e-01, 6.69720204e-02], 

215 [3.67470562e-01, 8.11691502e-02], [3.80987875e-01, 9.13148567e-02], 

216 [3.90738756e-01, 9.39276818e-02], [3.95854520e-01, 9.06728175e-02], 

217 [3.99717109e-01, 8.49081236e-02], [3.96997843e-01, 6.54750599e-02], 

218 [3.89101023e-01, 4.11631100e-02], [3.86289062e-01, 3.71837960e-02], 

219 [3.94553267e-01, 3.78052325e-02], [4.03373690e-01, 3.72181278e-02], 

220 [4.20207675e-01, 3.56696607e-02], [4.37553246e-01, 3.46018748e-02], 

221 [4.59139056e-01, 3.15068918e-02], [4.79811600e-01, 2.68634593e-02], 

222 [4.92810472e-01, 1.97499259e-02], [4.98594784e-01, 1.11517021e-02], 

223 [5.00000000e-01, 5.62393850e-03], [5.00000000e-01, -5.62393850e-03], 

224 [4.98594784e-01, -1.11517021e-02], [4.92810472e-01, -1.97499259e-02], 

225 [4.79811600e-01, -2.68634593e-02], [4.59139056e-01, -3.15068918e-02], 

226 [4.37553246e-01, -3.46018748e-02], [4.20207675e-01, -3.56696607e-02], 

227 [4.03373690e-01, -3.72181278e-02], [3.94553267e-01, -3.78052325e-02], 

228 [3.86289062e-01, -3.71837960e-02], [3.89101023e-01, -4.11631100e-02], 

229 [3.96997843e-01, -6.54750599e-02], [3.99717109e-01, -8.49081236e-02], 

230 [3.95854520e-01, -9.06728175e-02], [3.90738756e-01, -9.39276818e-02], 

231 [3.80987875e-01, -9.13148567e-02], [3.67470562e-01, -8.11691502e-02], 

232 [3.54784122e-01, -6.69720204e-02], [3.46387987e-01, -5.39648157e-02], 

233 [3.44207747e-01, -4.53621620e-02], [3.46108357e-01, -3.83290703e-02], 

234 [3.51347983e-01, -3.44809486e-02], [3.57215426e-01, -3.25163153e-02], 

235 [3.62525174e-01, -3.12766064e-02], [3.68462758e-01, -2.97229886e-02], 

236 [3.46646908e-01, -2.77590937e-02], [3.20834553e-01, -2.63067663e-02], 

237 [2.83582110e-01, -2.36895289e-02], [2.15041020e-01, -1.96734219e-02], 

238 [1.36968804e-01, -1.51550643e-02], [2.36080412e-02, -1.40941342e-02], 

239 [-1.35145770e-01, -1.09559947e-02], [-2.74106007e-01, -8.94059314e-03], 

240 [-3.94680346e-01, -8.25734868e-03], [-4.76913801e-01, -5.34924846e-03], 

241 [-4.84515329e-01, -4.41536208e-03], [-5.00000000e-01, -0.00000000e+00],])) 

242"""Outline of an *Eigenmannia virescens* viewed from top.""" 

243 

244Eigenmannia_side = dict(body=np.array([ 

245 [7.39835590e-02, 4.57421567e-02], [1.36190672e-01, 5.20008556e-02], 

246 [1.88575637e-01, 5.31087788e-02], [2.55693889e-01, 4.90162062e-02], 

247 [2.91989388e-01, 4.57421567e-02], [3.30997244e-01, 4.08310609e-02], 

248 [3.60079352e-01, 3.50312357e-02], [3.86267547e-01, 2.72057399e-02], 

249 [4.09748495e-01, 1.88510343e-02], [4.30914243e-01, 1.02069720e-02], 

250 [4.43253678e-01, 5.18028074e-03], [4.61959655e-01, -3.75313831e-03], 

251 [4.82422519e-01, -1.50677197e-02], [4.93493046e-01, -2.26243878e-02], 

252 [4.97325280e-01, -2.75603439e-02], [5.00000000e-01, -3.36538136e-02], 

253 [4.99855343e-01, -3.81556262e-02], [4.97829629e-01, -4.26574388e-02], 

254 [4.95229403e-01, -4.49683083e-02], [4.93207934e-01, -4.68450344e-02], 

255 [4.90607707e-01, -4.83870578e-02], [4.92124870e-01, -5.04085273e-02], 

256 [4.93063234e-01, -5.27193968e-02], [4.93063190e-01, -5.47905000e-02], 

257 [4.91905677e-01, -5.65722031e-02], [4.87982621e-01, -5.83539496e-02], 

258 [4.81889151e-01, -5.99909526e-02], [4.72187579e-01, -6.31614903e-02], 

259 [4.57251469e-01, -6.96684443e-02], [4.42315315e-01, -7.44390846e-02], 

260 [4.31434877e-01, -7.64563096e-02], [4.21852452e-01, -8.03091592e-02], 

261 [4.12030260e-01, -8.11773161e-02], [3.97297016e-01, -8.61380457e-02], 

262 [3.84200775e-01, -9.05200184e-02], [3.71589870e-01, -9.38291926e-02], 

263 [3.58008292e-01, -9.50424035e-02], [3.33452813e-01, -9.34053571e-02], 

264 [2.99075185e-01, -8.68572582e-02], [2.70427177e-01, -8.11276391e-02], 

265 [2.32775500e-01, -7.31023958e-02], [2.00034918e-01, -6.81912999e-02], 

266 [1.71386866e-01, -6.43481085e-02], [1.37488988e-01, -5.96768656e-02], 

267 [8.87168470e-02, -5.53444400e-02], [3.71504052e-02, -5.08426274e-02], 

268 [-8.94935470e-03, -4.47741911e-02], [-6.68009664e-02, -3.60218095e-02], 

269 [-1.11819296e-01, -3.02864735e-02], [-1.55609841e-01, -2.46444281e-02], 

270 [-2.01855938e-01, -1.98208625e-02], [-2.61607520e-01, -1.41655641e-02], 

271 [-3.02124011e-01, -9.83500080e-03], [-3.47551590e-01, -8.19795443e-03], 

272 [-3.86021794e-01, -7.21576125e-03], [-4.19580907e-01, -5.90618477e-03], 

273 [-4.49047446e-01, -5.00584824e-03], [-4.82606558e-01, -4.29793979e-03], 

274 [-4.93367213e-01, -3.88865654e-03], [-4.96609514e-01, -3.33497643e-03], 

275 [-4.98599358e-01, -2.28352992e-03], [-5.00000000e-01, -4.13646830e-04], 

276 [-4.99911798e-01, 1.42799787e-03], [-4.97749085e-01, 3.02268669e-03], 

277 [-4.94153971e-01, 3.94706050e-03], [-4.48842818e-01, 5.27946155e-03], 

278 [-3.90932887e-01, 5.88974836e-03], [-3.04988822e-01, 7.10408527e-03], 

279 [-2.43785835e-01, 8.93052803e-03], [-1.87718481e-01, 1.20250559e-02], 

280 [-1.39987578e-01, 1.55534240e-02], [-9.58582596e-02, 1.92113768e-02], 

281 [-4.87936436e-02, 2.54739303e-02], [-1.20172913e-02, 3.11685979e-02], 

282 [3.65545828e-02, 3.98634200e-02],]), 

283 fin0=np.array([ 

284 [-3.23227396e-01, -8.73526322e-03], [-3.17729007e-01, -1.49720903e-02], 

285 [-3.11901320e-01, -2.06301173e-02], [-2.94537996e-01, -2.87329729e-02], 

286 [-2.73702014e-01, -3.62471102e-02], [-2.48814582e-01, -4.42901541e-02], 

287 [-2.26392044e-01, -4.89203820e-02], [-2.11413629e-01, -4.97652813e-02], 

288 [-1.97592770e-01, -4.71608105e-02], [-1.88292360e-01, -4.37113973e-02], 

289 [-1.77575020e-01, -4.26201918e-02], [-1.63230314e-01, -4.13425351e-02], 

290 [-1.45633053e-01, -4.58128611e-02], [-1.32102997e-01, -5.21132245e-02], 

291 [-1.22627830e-01, -5.98022925e-02], [-1.16274541e-01, -6.51393895e-02], 

292 [-1.01226326e-01, -6.99292162e-02], [-8.87826127e-02, -7.09420732e-02], 

293 [-7.63388990e-02, -7.02186163e-02], [-6.41845810e-02, -6.63566715e-02], 

294 [-4.99997329e-02, -6.35107453e-02], [-3.86044383e-02, -6.71556184e-02], 

295 [-2.83003535e-02, -7.56835222e-02], [-1.41203129e-02, -8.28817968e-02], 

296 [1.21728460e-03, -8.66205668e-02], [1.22140543e-02, -8.75385740e-02], 

297 [2.16240177e-02, -8.43285373e-02], [3.27836777e-02, -8.13081568e-02], 

298 [3.98554860e-02, -8.02952999e-02], [4.86770343e-02, -7.96350762e-02], 

299 [5.81904230e-02, -8.20450399e-02], [6.47198980e-02, -8.65937577e-02], 

300 [7.29857310e-02, -9.36024194e-02], [8.47509570e-02, -9.91141438e-02], 

301 [1.00477612e-01, -1.02776515e-01], [1.28258936e-01, -1.02826321e-01], 

302 [1.45605097e-01, -1.02460349e-01], [1.59342462e-01, -9.97657918e-02], 

303 [1.76140399e-01, -9.72111283e-02], [1.89366052e-01, -9.61800377e-02], 

304 [2.03938918e-01, -9.84587276e-02], [2.14786136e-01, -1.02170949e-01], 

305 [2.24046592e-01, -1.08953357e-01], [2.34464605e-01, -1.14112491e-01], 

306 [2.47925953e-01, -1.18114112e-01], [2.65013334e-01, -1.19108779e-01], 

307 [2.83520819e-01, -1.15835465e-01], [2.98329467e-01, -1.08650574e-01], 

308 [3.15014321e-01, -1.04499489e-01], [3.28805304e-01, -1.04273408e-01], 

309 [3.39387031e-01, -1.06211982e-01], [3.52278630e-01, -1.03431974e-01], 

310 [3.61896180e-01, -1.00567165e-01], [3.67032403e-01, -9.80662488e-02], 

311 [3.71589870e-01, -9.38289761e-02], [3.58008292e-01, -9.50421869e-02], 

312 [3.33452813e-01, -9.34051405e-02], [3.06441808e-01, -8.84940880e-02], 

313 [2.35043362e-01, -7.35981699e-02], [1.65011316e-01, -6.31802003e-02], 

314 [1.25654422e-01, -5.85499724e-02], [9.49792270e-02, -5.56561016e-02], 

315 [4.05741354e-02, -5.11056947e-02], [-1.24746680e-03, -4.58268936e-02], 

316 [-5.20302500e-02, -3.81131387e-02], [-1.01805114e-01, -3.16101258e-02], 

317 [-1.51874267e-01, -2.50855445e-02], [-2.01943420e-01, -2.02074944e-02], 

318 [-2.61607516e-01, -1.41653476e-02], [-3.02124016e-01, -9.83478430e-03], 

319 [-3.12840355e-01, -9.28491550e-03],]), 

320 eye=np.array([0.46, -0.03, 0.005])) 

321"""Outline of an *Eigenmannia virescens* viewed from the side.""" 

322 

323Gpetersii_top = dict(body=np.array([ 

324 [-5.00000000e-01, 0.00000000e+00], [-4.98907255e-01, 2.70675451e-03], 

325 [-4.95224935e-01, 4.98692300e-03], [-4.90164100e-01, 6.33588717e-03], 

326 [-4.86097610e-01, 6.53956463e-03], [-4.82786611e-01, 6.60371808e-03], 

327 [-4.79368466e-01, 6.66911518e-03], [-4.75847352e-01, 6.73594857e-03], 

328 [-4.72227445e-01, 6.80441093e-03], [-4.68512920e-01, 6.87469491e-03], 

329 [-4.64707956e-01, 6.94699319e-03], [-4.60816728e-01, 7.02149842e-03], 

330 [-4.56843412e-01, 7.09840326e-03], [-4.52792185e-01, 7.17790040e-03], 

331 [-4.48667224e-01, 7.26018248e-03], [-4.44472704e-01, 7.34544217e-03], 

332 [-4.40212803e-01, 7.43387214e-03], [-4.35891696e-01, 7.52566504e-03], 

333 [-4.31513560e-01, 7.62101355e-03], [-4.27082571e-01, 7.72011032e-03], 

334 [-4.22602906e-01, 7.82314803e-03], [-4.18078741e-01, 7.93031933e-03], 

335 [-4.13514253e-01, 8.04181689e-03], [-4.08913618e-01, 8.15783338e-03], 

336 [-4.04281012e-01, 8.27856145e-03], [-3.99620612e-01, 8.40419377e-03], 

337 [-3.94936595e-01, 8.53492300e-03], [-3.90233135e-01, 8.67094182e-03], 

338 [-3.85514411e-01, 8.81244288e-03], [-3.80784598e-01, 8.95961884e-03], 

339 [-3.76047873e-01, 9.11266238e-03], [-3.71308412e-01, 9.27176615e-03], 

340 [-3.66570392e-01, 9.43712281e-03], [-3.61837989e-01, 9.60892505e-03], 

341 [-3.57115379e-01, 9.78736550e-03], [-3.52406739e-01, 9.97263685e-03], 

342 [-3.47716245e-01, 1.01649318e-02], [-3.43048074e-01, 1.03644429e-02], 

343 [-3.38406402e-01, 1.05713629e-02], [-3.33795405e-01, 1.07858844e-02], 

344 [-3.29219260e-01, 1.10082002e-02], [-3.24682143e-01, 1.12385028e-02], 

345 [-3.20188231e-01, 1.14769850e-02], [-3.15741700e-01, 1.17238394e-02], 

346 [-3.11346727e-01, 1.19792586e-02], [-3.07007487e-01, 1.22434354e-02], 

347 [-3.02469744e-01, 1.25292477e-02], [-2.97839001e-01, 1.28158813e-02], 

348 [-2.93275530e-01, 1.30920628e-02], [-2.88774618e-01, 1.33584584e-02], 

349 [-2.84331553e-01, 1.36157341e-02], [-2.79941621e-01, 1.38645562e-02], 

350 [-2.75600107e-01, 1.41055908e-02], [-2.71302299e-01, 1.43395042e-02], 

351 [-2.67043484e-01, 1.45669625e-02], [-2.62818947e-01, 1.47886318e-02], 

352 [-2.58623976e-01, 1.50051785e-02], [-2.54453857e-01, 1.52172685e-02], 

353 [-2.50303877e-01, 1.54255682e-02], [-2.46169321e-01, 1.56307436e-02], 

354 [-2.42045478e-01, 1.58334610e-02], [-2.37927633e-01, 1.60343865e-02], 

355 [-2.33811073e-01, 1.62341864e-02], [-2.29691084e-01, 1.64335267e-02], 

356 [-2.25562953e-01, 1.66330737e-02], [-2.21421967e-01, 1.68334935e-02], 

357 [-2.17263412e-01, 1.70354524e-02], [-2.13082575e-01, 1.72396165e-02], 

358 [-2.08874743e-01, 1.74466519e-02], [-2.04635201e-01, 1.76572249e-02], 

359 [-2.00359237e-01, 1.78720016e-02], [-1.96042137e-01, 1.80916482e-02], 

360 [-1.91679187e-01, 1.83168309e-02], [-1.87265675e-01, 1.85482158e-02], 

361 [-1.82796886e-01, 1.87864692e-02], [-1.78268108e-01, 1.90322571e-02], 

362 [-1.73674627e-01, 1.92862459e-02], [-1.69011730e-01, 1.95491016e-02], 

363 [-1.64274702e-01, 1.98214905e-02], [-1.59458831e-01, 2.01040786e-02], 

364 [-1.54876765e-01, 2.03808505e-02], [-1.50542259e-01, 2.06624447e-02], 

365 [-1.46207582e-01, 2.09641308e-02], [-1.41872739e-01, 2.12846589e-02], 

366 [-1.37537731e-01, 2.16227790e-02], [-1.33202563e-01, 2.19772413e-02], 

367 [-1.28867239e-01, 2.23467957e-02], [-1.24531760e-01, 2.27301926e-02], 

368 [-1.20196132e-01, 2.31261818e-02], [-1.15860356e-01, 2.35335136e-02], 

369 [-1.11524437e-01, 2.39509380e-02], [-1.07188379e-01, 2.43772051e-02], 

370 [-1.02852183e-01, 2.48110650e-02], [-9.85158544e-02, 2.52512678e-02], 

371 [-9.41793959e-02, 2.56965637e-02], [-8.98428110e-02, 2.61457026e-02], 

372 [-8.55061031e-02, 2.65974348e-02], [-8.11692756e-02, 2.70505102e-02], 

373 [-7.68323318e-02, 2.75036791e-02], [-7.24952752e-02, 2.79556914e-02], 

374 [-6.81581092e-02, 2.84052973e-02], [-6.38208372e-02, 2.88512469e-02], 

375 [-5.94834626e-02, 2.92922903e-02], [-5.51459887e-02, 2.97271776e-02], 

376 [-5.08084190e-02, 3.01546588e-02], [-4.64707569e-02, 3.05734841e-02], 

377 [-4.21330057e-02, 3.09824036e-02], [-3.77951689e-02, 3.13801673e-02], 

378 [-3.34572499e-02, 3.17655254e-02], [-2.91192521e-02, 3.21372280e-02], 

379 [-2.47811788e-02, 3.24940251e-02], [-2.04430334e-02, 3.28346669e-02], 

380 [-1.61048195e-02, 3.31579034e-02], [-1.17665402e-02, 3.34624847e-02], 

381 [-7.42819918e-03, 3.37471610e-02], [-3.08979968e-03, 3.40106823e-02], 

382 [1.24865487e-03, 3.42517987e-02], [5.58716106e-03, 3.44692604e-02], 

383 [9.92571550e-03, 3.46618174e-02], [1.46201447e-02, 3.48571853e-02], 

384 [1.92777267e-02, 3.50697277e-02], [2.37992814e-02, 3.52944714e-02], 

385 [2.81998991e-02, 3.55299272e-02], [3.24946703e-02, 3.57746059e-02], 

386 [3.66986852e-02, 3.60270183e-02], [4.08270342e-02, 3.62856753e-02], 

387 [4.48948076e-02, 3.65490876e-02], [4.89170960e-02, 3.68157661e-02], 

388 [5.29089894e-02, 3.70842215e-02], [5.68855785e-02, 3.73529647e-02], 

389 [6.08619534e-02, 3.76205066e-02], [6.48532046e-02, 3.78853578e-02], 

390 [6.88744224e-02, 3.81460293e-02], [7.29406971e-02, 3.84010318e-02], 

391 [7.70671192e-02, 3.86488761e-02], [8.12687789e-02, 3.88880731e-02], 

392 [8.55607667e-02, 3.91171336e-02], [8.99581728e-02, 3.93345683e-02], 

393 [9.44760878e-02, 3.95388881e-02], [9.91296018e-02, 3.97286039e-02], 

394 [1.03933805e-01, 3.99022264e-02], [1.08903789e-01, 4.00582663e-02], 

395 [1.14054642e-01, 4.01952347e-02], [1.17834449e-01, 4.02735051e-02], 

396 [1.21464088e-01, 4.03177574e-02], [1.25361081e-01, 4.03400333e-02], 

397 [1.29496398e-01, 4.03422149e-02], [1.33841006e-01, 4.03261843e-02], 

398 [1.38365875e-01, 4.02938238e-02], [1.43041974e-01, 4.02470155e-02], 

399 [1.47840270e-01, 4.01876413e-02], [1.52731734e-01, 4.01175836e-02], 

400 [1.57687333e-01, 4.00387245e-02], [1.62678036e-01, 3.99529460e-02], 

401 [1.67674813e-01, 3.98621303e-02], [1.72648631e-01, 3.97681595e-02], 

402 [1.77570460e-01, 3.96729159e-02], [1.82411269e-01, 3.95782814e-02], 

403 [1.87142025e-01, 3.94861383e-02], [1.91733698e-01, 3.93983686e-02], 

404 [1.96157257e-01, 3.93168546e-02], [2.00383670e-01, 3.92434783e-02], 

405 [2.04383906e-01, 3.91801218e-02], [2.08128934e-01, 3.91286674e-02], 

406 [2.11589723e-01, 3.90909971e-02], [2.14737240e-01, 3.90689931e-02], 

407 [2.12686797e-01, 4.35945731e-02], [2.09370932e-01, 4.90028591e-02], 

408 [2.06521214e-01, 5.37246134e-02], [2.04069750e-01, 5.78713813e-02], 

409 [2.01948645e-01, 6.15547081e-02], [2.00090006e-01, 6.48861392e-02], 

410 [1.98425939e-01, 6.79772197e-02], [1.96888549e-01, 7.09394950e-02], 

411 [1.95409943e-01, 7.38845104e-02], [1.93922227e-01, 7.69238111e-02], 

412 [1.92357507e-01, 8.01689425e-02], [1.90647889e-01, 8.37314498e-02], 

413 [1.88621089e-01, 8.79487819e-02], [1.86458315e-01, 9.24949589e-02], 

414 [1.84373392e-01, 9.69521163e-02], [1.82377447e-01, 1.01313322e-01], 

415 [1.80481608e-01, 1.05571643e-01], [1.78697002e-01, 1.09720148e-01], 

416 [1.77034758e-01, 1.13751904e-01], [1.75506002e-01, 1.17659979e-01], 

417 [1.74121863e-01, 1.21437441e-01], [1.72893469e-01, 1.25077357e-01], 

418 [1.71831946e-01, 1.28572795e-01], [1.70912462e-01, 1.32062919e-01], 

419 [1.69673781e-01, 1.37398586e-01], [1.68551414e-01, 1.42827662e-01], 

420 [1.67594629e-01, 1.48234120e-01], [1.66852697e-01, 1.53501933e-01], 

421 [1.66374886e-01, 1.58515074e-01], [1.66210468e-01, 1.63157516e-01], 

422 [1.66408711e-01, 1.67313232e-01], [1.67018885e-01, 1.70866193e-01], 

423 [1.68090261e-01, 1.73700374e-01], [1.69672107e-01, 1.75699747e-01], 

424 [1.71946252e-01, 1.76778701e-01], [1.75330935e-01, 1.76759167e-01], 

425 [1.79335065e-01, 1.75658590e-01], [1.83654362e-01, 1.73730954e-01], 

426 [1.87984545e-01, 1.71230243e-01], [1.92021332e-01, 1.68410438e-01], 

427 [1.95460443e-01, 1.65525524e-01], [1.98288699e-01, 1.62567524e-01], 

428 [2.01008859e-01, 1.59273085e-01], [2.03549954e-01, 1.55804760e-01], 

429 [2.05927459e-01, 1.52185189e-01], [2.08156845e-01, 1.48437015e-01], 

430 [2.10253586e-01, 1.44582880e-01], [2.12233153e-01, 1.40645424e-01], 

431 [2.14111019e-01, 1.36647290e-01], [2.15902657e-01, 1.32611119e-01], 

432 [2.17623539e-01, 1.28559552e-01], [2.19289138e-01, 1.24515232e-01], 

433 [2.20914927e-01, 1.20500800e-01], [2.22516621e-01, 1.16537119e-01], 

434 [2.24093642e-01, 1.12596583e-01], [2.25635202e-01, 1.08661555e-01], 

435 [2.27140388e-01, 1.04726305e-01], [2.28608285e-01, 1.00785102e-01], 

436 [2.30037979e-01, 9.68322151e-02], [2.31428556e-01, 9.28619142e-02], 

437 [2.32779102e-01, 8.88684682e-02], [2.34088702e-01, 8.48461463e-02], 

438 [2.35356443e-01, 8.07892177e-02], [2.36581411e-01, 7.66919517e-02], 

439 [2.37762692e-01, 7.25486175e-02], [2.38899370e-01, 6.83534843e-02], 

440 [2.39990533e-01, 6.41008214e-02], [2.41035267e-01, 5.97848980e-02], 

441 [2.42032656e-01, 5.53999834e-02], [2.42981787e-01, 5.09403468e-02], 

442 [2.43881746e-01, 4.64002574e-02], [2.44731618e-01, 4.17739844e-02], 

443 [2.48004373e-01, 3.96335251e-02], [2.53635676e-01, 4.06269030e-02], 

444 [2.58426595e-01, 4.15200350e-02], [2.62587153e-01, 4.23139380e-02], 

445 [2.66327377e-01, 4.30096290e-02], [2.69857289e-01, 4.36081248e-02], 

446 [2.73386916e-01, 4.41104425e-02], [2.77136095e-01, 4.45185137e-02], 

447 [2.81686172e-01, 4.49167415e-02], [2.86059572e-01, 4.52505561e-02], 

448 [2.90315087e-01, 4.55181830e-02], [2.94511509e-01, 4.57178472e-02], 

449 [2.98707633e-01, 4.58477742e-02], [3.02962251e-01, 4.59061892e-02], 

450 [3.07334157e-01, 4.58913175e-02], [3.11882144e-01, 4.58013842e-02], 

451 [3.16163999e-01, 4.56260578e-02], [3.20364728e-01, 4.53392745e-02], 

452 [3.24552010e-01, 4.49599161e-02], [3.28754468e-01, 4.45083053e-02], 

453 [3.33000723e-01, 4.40047646e-02], [3.37319396e-01, 4.34696166e-02], 

454 [3.41739110e-01, 4.29231841e-02], [3.46288486e-01, 4.23857894e-02], 

455 [3.50619754e-01, 4.29679988e-02], [3.54195757e-01, 4.55158258e-02], 

456 [3.58046266e-01, 4.57683865e-02], [3.61404779e-01, 4.41255618e-02], 

457 [3.64409935e-01, 4.03824460e-02], [3.68329272e-01, 3.86496012e-02], 

458 [3.72644259e-01, 3.78587189e-02], [3.76950817e-01, 3.70760234e-02], 

459 [3.81238037e-01, 3.62610245e-02], [3.85495013e-01, 3.53732317e-02], 

460 [3.89710839e-01, 3.43721549e-02], [3.93874609e-01, 3.32173035e-02], 

461 [3.97975415e-01, 3.18681874e-02], [4.02040813e-01, 3.03843958e-02], 

462 [4.06171694e-01, 2.88827227e-02], [4.10325795e-01, 2.73247743e-02], 

463 [4.14453652e-01, 2.56705391e-02], [4.18505801e-01, 2.38800060e-02], 

464 [4.22432777e-01, 2.19131636e-02], [4.26185115e-01, 1.97300005e-02], 

465 [4.29713351e-01, 1.72905055e-02], [4.32968019e-01, 1.45546672e-02], 

466 [4.35899655e-01, 1.14824744e-02], [4.37947185e-01, 9.20518422e-03], 

467 [4.40409231e-01, 8.23893126e-03], [4.43933454e-01, 7.71247651e-03], 

468 [4.48362633e-01, 7.48160487e-03], [4.53539545e-01, 7.40210123e-03], 

469 [4.59306972e-01, 7.32975048e-03], [4.65888477e-01, 7.11072685e-03], 

470 [4.72579311e-01, 6.83103276e-03], [4.77520884e-01, 6.62053683e-03], 

471 [4.81282017e-01, 6.44392261e-03], [4.84431531e-01, 6.26587366e-03], 

472 [4.87538245e-01, 6.05107355e-03], [4.91170982e-01, 5.76420583e-03], 

473 [4.96599033e-01, 4.75791906e-03], [5.00000000e-01, 2.45820721e-03], 

474 [5.00000000e-01, -2.45820721e-03], [4.96599033e-01, -4.75791906e-03], 

475 [4.91170982e-01, -5.76420583e-03], [4.87538245e-01, -6.05107355e-03], 

476 [4.84431531e-01, -6.26587366e-03], [4.81282017e-01, -6.44392261e-03], 

477 [4.77520884e-01, -6.62053683e-03], [4.72579311e-01, -6.83103276e-03], 

478 [4.65888477e-01, -7.11072685e-03], [4.59306972e-01, -7.32975048e-03], 

479 [4.53539545e-01, -7.40210123e-03], [4.48362633e-01, -7.48160487e-03], 

480 [4.43933454e-01, -7.71247651e-03], [4.40409231e-01, -8.23893126e-03], 

481 [4.37947185e-01, -9.20518422e-03], [4.35899655e-01, -1.14824744e-02], 

482 [4.32968019e-01, -1.45546672e-02], [4.29713351e-01, -1.72905055e-02], 

483 [4.26185115e-01, -1.97300005e-02], [4.22432777e-01, -2.19131636e-02], 

484 [4.18505801e-01, -2.38800060e-02], [4.14453652e-01, -2.56705391e-02], 

485 [4.10325795e-01, -2.73247743e-02], [4.06171694e-01, -2.88827227e-02], 

486 [4.02040813e-01, -3.03843958e-02], [3.97975415e-01, -3.18681874e-02], 

487 [3.93874609e-01, -3.32173035e-02], [3.89710839e-01, -3.43721549e-02], 

488 [3.85495013e-01, -3.53732317e-02], [3.81238037e-01, -3.62610245e-02], 

489 [3.76950817e-01, -3.70760234e-02], [3.72644259e-01, -3.78587189e-02], 

490 [3.68329272e-01, -3.86496012e-02], [3.64409935e-01, -4.03824460e-02], 

491 [3.61404779e-01, -4.41255618e-02], [3.58046266e-01, -4.57683865e-02], 

492 [3.54195757e-01, -4.55158258e-02], [3.50619754e-01, -4.29679988e-02], 

493 [3.46288486e-01, -4.23857894e-02], [3.41739110e-01, -4.29231841e-02], 

494 [3.37319396e-01, -4.34696166e-02], [3.33000723e-01, -4.40047646e-02], 

495 [3.28754468e-01, -4.45083053e-02], [3.24552010e-01, -4.49599161e-02], 

496 [3.20364728e-01, -4.53392745e-02], [3.16163999e-01, -4.56260578e-02], 

497 [3.11882144e-01, -4.58013842e-02], [3.07334157e-01, -4.58913175e-02], 

498 [3.02962251e-01, -4.59061892e-02], [2.98707633e-01, -4.58477742e-02], 

499 [2.94511509e-01, -4.57178472e-02], [2.90315087e-01, -4.55181830e-02], 

500 [2.86059572e-01, -4.52505561e-02], [2.81686172e-01, -4.49167415e-02], 

501 [2.77136095e-01, -4.45185137e-02], [2.73386916e-01, -4.41104425e-02], 

502 [2.69857289e-01, -4.36081248e-02], [2.66327377e-01, -4.30096290e-02], 

503 [2.62587153e-01, -4.23139380e-02], [2.58426595e-01, -4.15200350e-02], 

504 [2.53635676e-01, -4.06269030e-02], [2.48004373e-01, -3.96335251e-02], 

505 [2.44731618e-01, -4.17739844e-02], [2.43881746e-01, -4.64002574e-02], 

506 [2.42981787e-01, -5.09403468e-02], [2.42032656e-01, -5.53999834e-02], 

507 [2.41035267e-01, -5.97848980e-02], [2.39990533e-01, -6.41008214e-02], 

508 [2.38899370e-01, -6.83534843e-02], [2.37762692e-01, -7.25486175e-02], 

509 [2.36581411e-01, -7.66919517e-02], [2.35356443e-01, -8.07892177e-02], 

510 [2.34088702e-01, -8.48461463e-02], [2.32779102e-01, -8.88684682e-02], 

511 [2.31428556e-01, -9.28619142e-02], [2.30037979e-01, -9.68322151e-02], 

512 [2.28608285e-01, -1.00785102e-01], [2.27140388e-01, -1.04726305e-01], 

513 [2.25635202e-01, -1.08661555e-01], [2.24093642e-01, -1.12596583e-01], 

514 [2.22516621e-01, -1.16537119e-01], [2.20914927e-01, -1.20500800e-01], 

515 [2.19289138e-01, -1.24515232e-01], [2.17623539e-01, -1.28559552e-01], 

516 [2.15902657e-01, -1.32611119e-01], [2.14111019e-01, -1.36647290e-01], 

517 [2.12233153e-01, -1.40645424e-01], [2.10253586e-01, -1.44582880e-01], 

518 [2.08156845e-01, -1.48437015e-01], [2.05927459e-01, -1.52185189e-01], 

519 [2.03549954e-01, -1.55804760e-01], [2.01008859e-01, -1.59273085e-01], 

520 [1.98288699e-01, -1.62567524e-01], [1.95460443e-01, -1.65525524e-01], 

521 [1.92021332e-01, -1.68410438e-01], [1.87984545e-01, -1.71230243e-01], 

522 [1.83654362e-01, -1.73730954e-01], [1.79335065e-01, -1.75658590e-01], 

523 [1.75330935e-01, -1.76759167e-01], [1.71946252e-01, -1.76778701e-01], 

524 [1.69672107e-01, -1.75699747e-01], [1.68090261e-01, -1.73700374e-01], 

525 [1.67018885e-01, -1.70866193e-01], [1.66408711e-01, -1.67313232e-01], 

526 [1.66210468e-01, -1.63157516e-01], [1.66374886e-01, -1.58515074e-01], 

527 [1.66852697e-01, -1.53501933e-01], [1.67594629e-01, -1.48234120e-01], 

528 [1.68551414e-01, -1.42827662e-01], [1.69673781e-01, -1.37398586e-01], 

529 [1.70912462e-01, -1.32062919e-01], [1.71831946e-01, -1.28572795e-01], 

530 [1.72893469e-01, -1.25077357e-01], [1.74121863e-01, -1.21437441e-01], 

531 [1.75506002e-01, -1.17659979e-01], [1.77034758e-01, -1.13751904e-01], 

532 [1.78697002e-01, -1.09720148e-01], [1.80481608e-01, -1.05571643e-01], 

533 [1.82377447e-01, -1.01313322e-01], [1.84373392e-01, -9.69521163e-02], 

534 [1.86458315e-01, -9.24949589e-02], [1.88621089e-01, -8.79487819e-02], 

535 [1.90647889e-01, -8.37314498e-02], [1.92357507e-01, -8.01689425e-02], 

536 [1.93922227e-01, -7.69238111e-02], [1.95409943e-01, -7.38845104e-02], 

537 [1.96888549e-01, -7.09394950e-02], [1.98425939e-01, -6.79772197e-02], 

538 [2.00090006e-01, -6.48861392e-02], [2.01948645e-01, -6.15547081e-02], 

539 [2.04069750e-01, -5.78713813e-02], [2.06521214e-01, -5.37246134e-02], 

540 [2.09370932e-01, -4.90028591e-02], [2.12686797e-01, -4.35945731e-02], 

541 [2.14737240e-01, -3.90689931e-02], [2.11589723e-01, -3.90909971e-02], 

542 [2.08128934e-01, -3.91286674e-02], [2.04383906e-01, -3.91801218e-02], 

543 [2.00383670e-01, -3.92434783e-02], [1.96157257e-01, -3.93168546e-02], 

544 [1.91733698e-01, -3.93983686e-02], [1.87142025e-01, -3.94861383e-02], 

545 [1.82411269e-01, -3.95782814e-02], [1.77570460e-01, -3.96729159e-02], 

546 [1.72648631e-01, -3.97681595e-02], [1.67674813e-01, -3.98621303e-02], 

547 [1.62678036e-01, -3.99529460e-02], [1.57687333e-01, -4.00387245e-02], 

548 [1.52731734e-01, -4.01175836e-02], [1.47840270e-01, -4.01876413e-02], 

549 [1.43041974e-01, -4.02470155e-02], [1.38365875e-01, -4.02938238e-02], 

550 [1.33841006e-01, -4.03261843e-02], [1.29496398e-01, -4.03422149e-02], 

551 [1.25361081e-01, -4.03400333e-02], [1.21464088e-01, -4.03177574e-02], 

552 [1.17834449e-01, -4.02735051e-02], [1.14054642e-01, -4.01952347e-02], 

553 [1.08903789e-01, -4.00582663e-02], [1.03933805e-01, -3.99022264e-02], 

554 [9.91296018e-02, -3.97286039e-02], [9.44760878e-02, -3.95388881e-02], 

555 [8.99581728e-02, -3.93345683e-02], [8.55607667e-02, -3.91171336e-02], 

556 [8.12687789e-02, -3.88880731e-02], [7.70671192e-02, -3.86488761e-02], 

557 [7.29406971e-02, -3.84010318e-02], [6.88744224e-02, -3.81460293e-02], 

558 [6.48532046e-02, -3.78853578e-02], [6.08619534e-02, -3.76205066e-02], 

559 [5.68855785e-02, -3.73529647e-02], [5.29089894e-02, -3.70842215e-02], 

560 [4.89170960e-02, -3.68157661e-02], [4.48948076e-02, -3.65490876e-02], 

561 [4.08270342e-02, -3.62856753e-02], [3.66986852e-02, -3.60270183e-02], 

562 [3.24946703e-02, -3.57746059e-02], [2.81998991e-02, -3.55299272e-02], 

563 [2.37992814e-02, -3.52944714e-02], [1.92777267e-02, -3.50697277e-02], 

564 [1.46201447e-02, -3.48571853e-02], [9.92571550e-03, -3.46618174e-02], 

565 [5.58716106e-03, -3.44692604e-02], [1.24865487e-03, -3.42517987e-02], 

566 [-3.08979968e-03, -3.40106823e-02], [-7.42819918e-03, -3.37471610e-02], 

567 [-1.17665402e-02, -3.34624847e-02], [-1.61048195e-02, -3.31579034e-02], 

568 [-2.04430334e-02, -3.28346669e-02], [-2.47811788e-02, -3.24940251e-02], 

569 [-2.91192521e-02, -3.21372280e-02], [-3.34572499e-02, -3.17655254e-02], 

570 [-3.77951689e-02, -3.13801673e-02], [-4.21330057e-02, -3.09824036e-02], 

571 [-4.64707569e-02, -3.05734841e-02], [-5.08084190e-02, -3.01546588e-02], 

572 [-5.51459887e-02, -2.97271776e-02], [-5.94834626e-02, -2.92922903e-02], 

573 [-6.38208372e-02, -2.88512469e-02], [-6.81581092e-02, -2.84052973e-02], 

574 [-7.24952752e-02, -2.79556914e-02], [-7.68323318e-02, -2.75036791e-02], 

575 [-8.11692756e-02, -2.70505102e-02], [-8.55061031e-02, -2.65974348e-02], 

576 [-8.98428110e-02, -2.61457026e-02], [-9.41793959e-02, -2.56965637e-02], 

577 [-9.85158544e-02, -2.52512678e-02], [-1.02852183e-01, -2.48110650e-02], 

578 [-1.07188379e-01, -2.43772051e-02], [-1.11524437e-01, -2.39509380e-02], 

579 [-1.15860356e-01, -2.35335136e-02], [-1.20196132e-01, -2.31261818e-02], 

580 [-1.24531760e-01, -2.27301926e-02], [-1.28867239e-01, -2.23467957e-02], 

581 [-1.33202563e-01, -2.19772413e-02], [-1.37537731e-01, -2.16227790e-02], 

582 [-1.41872739e-01, -2.12846589e-02], [-1.46207582e-01, -2.09641308e-02], 

583 [-1.50542259e-01, -2.06624447e-02], [-1.54876765e-01, -2.03808505e-02], 

584 [-1.59458831e-01, -2.01040786e-02], [-1.64274702e-01, -1.98214905e-02], 

585 [-1.69011730e-01, -1.95491016e-02], [-1.73674627e-01, -1.92862459e-02], 

586 [-1.78268108e-01, -1.90322571e-02], [-1.82796886e-01, -1.87864692e-02], 

587 [-1.87265675e-01, -1.85482158e-02], [-1.91679187e-01, -1.83168309e-02], 

588 [-1.96042137e-01, -1.80916482e-02], [-2.00359237e-01, -1.78720016e-02], 

589 [-2.04635201e-01, -1.76572249e-02], [-2.08874743e-01, -1.74466519e-02], 

590 [-2.13082575e-01, -1.72396165e-02], [-2.17263412e-01, -1.70354524e-02], 

591 [-2.21421967e-01, -1.68334935e-02], [-2.25562953e-01, -1.66330737e-02], 

592 [-2.29691084e-01, -1.64335267e-02], [-2.33811073e-01, -1.62341864e-02], 

593 [-2.37927633e-01, -1.60343865e-02], [-2.42045478e-01, -1.58334610e-02], 

594 [-2.46169321e-01, -1.56307436e-02], [-2.50303877e-01, -1.54255682e-02], 

595 [-2.54453857e-01, -1.52172685e-02], [-2.58623976e-01, -1.50051785e-02], 

596 [-2.62818947e-01, -1.47886318e-02], [-2.67043484e-01, -1.45669625e-02], 

597 [-2.71302299e-01, -1.43395042e-02], [-2.75600107e-01, -1.41055908e-02], 

598 [-2.79941621e-01, -1.38645562e-02], [-2.84331553e-01, -1.36157341e-02], 

599 [-2.88774618e-01, -1.33584584e-02], [-2.93275530e-01, -1.30920628e-02], 

600 [-2.97839001e-01, -1.28158813e-02], [-3.02469744e-01, -1.25292477e-02], 

601 [-3.07007487e-01, -1.22434354e-02], [-3.11346727e-01, -1.19792586e-02], 

602 [-3.15741700e-01, -1.17238394e-02], [-3.20188231e-01, -1.14769850e-02], 

603 [-3.24682143e-01, -1.12385028e-02], [-3.29219260e-01, -1.10082002e-02], 

604 [-3.33795405e-01, -1.07858844e-02], [-3.38406402e-01, -1.05713629e-02], 

605 [-3.43048074e-01, -1.03644429e-02], [-3.47716245e-01, -1.01649318e-02], 

606 [-3.52406739e-01, -9.97263685e-03], [-3.57115379e-01, -9.78736550e-03], 

607 [-3.61837989e-01, -9.60892505e-03], [-3.66570392e-01, -9.43712281e-03], 

608 [-3.71308412e-01, -9.27176615e-03], [-3.76047873e-01, -9.11266238e-03], 

609 [-3.80784598e-01, -8.95961884e-03], [-3.85514411e-01, -8.81244288e-03], 

610 [-3.90233135e-01, -8.67094182e-03], [-3.94936595e-01, -8.53492300e-03], 

611 [-3.99620612e-01, -8.40419377e-03], [-4.04281012e-01, -8.27856145e-03], 

612 [-4.08913618e-01, -8.15783338e-03], [-4.13514253e-01, -8.04181689e-03], 

613 [-4.18078741e-01, -7.93031933e-03], [-4.22602906e-01, -7.82314803e-03], 

614 [-4.27082571e-01, -7.72011032e-03], [-4.31513560e-01, -7.62101355e-03], 

615 [-4.35891696e-01, -7.52566504e-03], [-4.40212803e-01, -7.43387214e-03], 

616 [-4.44472704e-01, -7.34544217e-03], [-4.48667224e-01, -7.26018248e-03], 

617 [-4.52792185e-01, -7.17790040e-03], [-4.56843412e-01, -7.09840326e-03], 

618 [-4.60816728e-01, -7.02149842e-03], [-4.64707956e-01, -6.94699319e-03], 

619 [-4.68512920e-01, -6.87469491e-03], [-4.72227445e-01, -6.80441093e-03], 

620 [-4.75847352e-01, -6.73594857e-03], [-4.79368466e-01, -6.66911518e-03], 

621 [-4.82786611e-01, -6.60371808e-03], [-4.86097610e-01, -6.53956463e-03], 

622 [-4.90164100e-01, -6.33588717e-03], [-4.95224935e-01, -4.98692300e-03], 

623 [-4.98907255e-01, -2.70675451e-03], [-5.00000000e-01, -0.00000000e+00],])) 

624"""Outline of an *Gnathonemus petersii* viewed from top.""" 

625 

626Gpetersii_side = dict(body=np.array([ 

627 [3.28398160e-01, 5.06559092e-02], [3.19199094e-01, 5.38197145e-02], 

628 [3.11056574e-01, 5.67169119e-02], [3.03696263e-01, 5.93946914e-02], 

629 [2.96843822e-01, 6.19002432e-02], [2.90224916e-01, 6.42807572e-02], 

630 [2.83565204e-01, 6.65834236e-02], [2.76590351e-01, 6.88554323e-02], 

631 [2.69026018e-01, 7.11439734e-02], [2.60597868e-01, 7.34962371e-02], 

632 [2.51261770e-01, 7.59025132e-02], [2.43304744e-01, 7.78395380e-02], 

633 [2.35356403e-01, 7.96898763e-02], [2.27413394e-01, 8.14533275e-02], 

634 [2.19472365e-01, 8.31296909e-02], [2.11529962e-01, 8.47187659e-02], 

635 [2.03582833e-01, 8.62203518e-02], [1.95627625e-01, 8.76342480e-02], 

636 [1.87660985e-01, 8.89602539e-02], [1.79679560e-01, 9.01981688e-02], 

637 [1.71679998e-01, 9.13477919e-02], [1.63658946e-01, 9.24089228e-02], 

638 [1.55613050e-01, 9.33813608e-02], [1.47538958e-01, 9.42649051e-02], 

639 [1.39433318e-01, 9.50593552e-02], [1.31292776e-01, 9.57645104e-02], 

640 [1.23120936e-01, 9.63719552e-02], [1.14971217e-01, 9.67676996e-02], 

641 [1.06847368e-01, 9.69472966e-02], [9.87430764e-02, 9.69522341e-02], 

642 [9.06520304e-02, 9.68239998e-02], [8.25679181e-02, 9.66040816e-02], 

643 [7.44844274e-02, 9.63339672e-02], [6.63952465e-02, 9.60551445e-02], 

644 [5.82940635e-02, 9.58091011e-02], [5.01745663e-02, 9.56373250e-02], 

645 [4.20304431e-02, 9.55813039e-02], [3.38553820e-02, 9.56825256e-02], 

646 [2.57298350e-02, 9.58827923e-02], [1.76079099e-02, 9.60920363e-02], 

647 [9.48768052e-03, 9.63204279e-02], [1.36979063e-03, 9.65782091e-02], 

648 [-6.74511599e-03, 9.68756218e-02], [-1.48563955e-02, 9.72229079e-02], 

649 [-2.29634043e-02, 9.76303093e-02], [-3.10654983e-02, 9.81080680e-02], 

650 [-3.91620340e-02, 9.86664259e-02], [-4.72523675e-02, 9.93156249e-02], 

651 [-5.53358549e-02, 1.00065907e-01], [-6.34118526e-02, 1.00927514e-01], 

652 [-7.18993466e-02, 1.02261625e-01], [-8.11969648e-02, 1.04253362e-01], 

653 [-8.90809864e-02, 1.05638275e-01], [-9.53015070e-02, 1.04903992e-01], 

654 [-1.02836258e-01, 1.02264667e-01], [-1.10086242e-01, 9.86850726e-02], 

655 [-1.17131132e-01, 9.44949291e-02], [-1.24050604e-01, 9.00239548e-02], 

656 [-1.30924330e-01, 8.56018686e-02], [-1.37851925e-01, 8.14694061e-02], 

657 [-1.44838326e-01, 7.73740401e-02], [-1.51858499e-01, 7.32981929e-02], 

658 [-1.58924240e-01, 6.92790656e-02], [-1.66047343e-01, 6.53538597e-02], 

659 [-1.73239603e-01, 6.15597764e-02], [-1.80512814e-01, 5.79340171e-02], 

660 [-1.87878771e-01, 5.45137830e-02], [-1.95349269e-01, 5.13362755e-02], 

661 [-2.02936102e-01, 4.84386959e-02], [-2.10670820e-01, 4.57953884e-02], 

662 [-2.18446301e-01, 4.33277308e-02], [-2.26244579e-01, 4.10351911e-02], 

663 [-2.34068253e-01, 3.89156690e-02], [-2.41919921e-01, 3.69670639e-02], 

664 [-2.49802182e-01, 3.51872756e-02], [-2.57717636e-01, 3.35742036e-02], 

665 [-2.65668880e-01, 3.21257476e-02], [-2.73658515e-01, 3.08398071e-02], 

666 [-2.81689139e-01, 2.97142819e-02], [-2.89763351e-01, 2.87470714e-02], 

667 [-2.97883750e-01, 2.79360754e-02], [-3.06009884e-01, 2.72879374e-02], 

668 [-3.14146832e-01, 2.68972145e-02], [-3.22397750e-01, 2.67791098e-02], 

669 [-3.30694484e-01, 2.69229164e-02], [-3.38968880e-01, 2.73179271e-02], 

670 [-3.47152784e-01, 2.79534348e-02], [-3.55178043e-01, 2.88187325e-02], 

671 [-3.62976502e-01, 2.99031130e-02], [-3.69491245e-01, 3.10922787e-02], 

672 [-3.75027729e-01, 3.30847269e-02], [-3.81405217e-01, 3.62096529e-02], 

673 [-3.88406343e-01, 4.02454207e-02], [-3.95813736e-01, 4.49703940e-02], 

674 [-4.03410029e-01, 5.01629368e-02], [-4.10977853e-01, 5.56014128e-02], 

675 [-4.18299839e-01, 6.10641860e-02], [-4.25158619e-01, 6.63296202e-02], 

676 [-4.31760708e-01, 7.17542834e-02], [-4.38394579e-01, 7.77938083e-02], 

677 [-4.44929264e-01, 8.41654014e-02], [-4.51237520e-01, 9.05858251e-02], 

678 [-4.57192105e-01, 9.67718415e-02], [-4.62665777e-01, 1.02440213e-01], 

679 [-4.67531294e-01, 1.07307702e-01], [-4.71931542e-01, 1.11312203e-01], 

680 [-4.78923098e-01, 1.15752170e-01], [-4.86766570e-01, 1.17829063e-01], 

681 [-4.94275150e-01, 1.15910154e-01], [-5.00000000e-01, 1.10078411e-01], 

682 [-4.99192237e-01, 1.02492362e-01], [-4.95460406e-01, 9.53394385e-02], 

683 [-4.90446832e-01, 8.86539346e-02], [-4.85474910e-01, 8.23552411e-02], 

684 [-4.80116940e-01, 7.63023767e-02], [-4.74386527e-01, 7.03935158e-02], 

685 [-4.68507746e-01, 6.45968551e-02], [-4.62704674e-01, 5.88805917e-02], 

686 [-4.57087282e-01, 5.31415261e-02], [-4.51221030e-01, 4.74785794e-02], 

687 [-4.45249806e-01, 4.20462447e-02], [-4.39272028e-01, 3.66480353e-02], 

688 [-4.33386114e-01, 3.10874644e-02], [-4.27293901e-01, 2.49068083e-02], 

689 [-4.21087150e-01, 1.80749383e-02], [-4.16972691e-01, 1.18889928e-02], 

690 [-4.14100660e-01, 5.57059642e-03], [-4.13927617e-01, -2.87320530e-03], 

691 [-4.16518117e-01, -1.03191259e-02], [-4.21249030e-01, -1.68743839e-02], 

692 [-4.26080311e-01, -2.35119600e-02], [-4.31143825e-01, -2.98817748e-02], 

693 [-4.36565107e-01, -3.57666535e-02], [-4.42259695e-01, -4.15631093e-02], 

694 [-4.48046856e-01, -4.73643011e-02], [-4.53759024e-01, -5.32064303e-02], 

695 [-4.59228634e-01, -5.91256981e-02], [-4.64931315e-01, -6.50893424e-02], 

696 [-4.70589921e-01, -7.07522385e-02], [-4.75576511e-01, -7.69772899e-02], 

697 [-4.78536384e-01, -8.45179044e-02], [-4.74937079e-01, -9.12035958e-02], 

698 [-4.66829596e-01, -9.29521810e-02], [-4.61234889e-01, -9.14597979e-02], 

699 [-4.55669467e-01, -8.90770697e-02], [-4.49258458e-01, -8.57384117e-02], 

700 [-4.42087882e-01, -8.14195162e-02], [-4.34243761e-01, -7.60960754e-02], 

701 [-4.25812116e-01, -6.97437814e-02], [-4.17545810e-01, -6.28897517e-02], 

702 [-4.10849771e-01, -5.68192385e-02], [-4.05159512e-01, -5.14279217e-02], 

703 [-3.99837805e-01, -4.65592652e-02], [-3.94247419e-01, -4.20567325e-02], 

704 [-3.87639055e-01, -3.76642221e-02], [-3.80497028e-01, -3.35435708e-02], 

705 [-3.73372036e-01, -2.99473943e-02], [-3.66154758e-01, -2.67737367e-02], 

706 [-3.58735871e-01, -2.39206424e-02], [-3.51006055e-01, -2.12861559e-02], 

707 [-3.43031055e-01, -1.88366028e-02], [-3.35174557e-01, -1.68266393e-02], 

708 [-3.27215655e-01, -1.52099446e-02], [-3.19183889e-01, -1.39534630e-02], 

709 [-3.11108797e-01, -1.30241389e-02], [-3.03019606e-01, -1.23889110e-02], 

710 [-2.94902329e-01, -1.21051718e-02], [-2.86785465e-01, -1.22505295e-02], 

711 [-2.78689352e-01, -1.28241713e-02], [-2.70634327e-01, -1.38252844e-02], 

712 [-2.62640729e-01, -1.52530562e-02], [-2.54843728e-01, -1.70549007e-02], 

713 [-2.47426741e-01, -1.90690048e-02], [-2.40252617e-01, -2.12696898e-02], 

714 [-2.33188150e-01, -2.36395350e-02], [-2.26100136e-01, -2.61611196e-02], 

715 [-2.18855371e-01, -2.88170232e-02], [-2.11320649e-01, -3.15898249e-02], 

716 [-2.03362765e-01, -3.44621040e-02], [-1.94848516e-01, -3.74164400e-02], 

717 [-1.85644696e-01, -4.04354121e-02], [-1.77857648e-01, -4.29185708e-02], 

718 [-1.70156514e-01, -4.54297763e-02], [-1.62430938e-01, -4.80126941e-02], 

719 [-1.54702578e-01, -5.06686981e-02], [-1.46993089e-01, -5.33991620e-02], 

720 [-1.39324130e-01, -5.62054598e-02], [-1.31717358e-01, -5.90889651e-02], 

721 [-1.24194428e-01, -6.20510518e-02], [-1.15662563e-01, -6.55718263e-02], 

722 [-1.05305133e-01, -7.02341332e-02], [-9.63092593e-02, -7.46194507e-02], 

723 [-8.86323630e-02, -7.85171774e-02], [-8.22318645e-02, -8.17167120e-02], 

724 [-7.70651844e-02, -8.40074533e-02], [-7.27307320e-02, -8.52544279e-02], 

725 [-6.61297323e-02, -8.61569494e-02], [-5.88746549e-02, -8.65921485e-02], 

726 [-5.10837990e-02, -8.66425980e-02], [-4.28754638e-02, -8.63908707e-02], 

727 [-3.43679487e-02, -8.59195395e-02], [-2.56795531e-02, -8.53111772e-02], 

728 [-1.69285762e-02, -8.46483565e-02], [-8.23331730e-03, -8.40136504e-02], 

729 [2.87924220e-04, -8.34896316e-02], [8.52573555e-03, -8.31566770e-02], 

730 [1.66602603e-02, -8.29060392e-02], [2.47824955e-02, -8.26453400e-02], 

731 [3.28955760e-02, -8.23839938e-02], [4.10026368e-02, -8.21314148e-02], 

732 [4.91068127e-02, -8.18970175e-02], [5.72112386e-02, -8.16902162e-02], 

733 [6.53190496e-02, -8.15204252e-02], [7.34333805e-02, -8.13970590e-02], 

734 [8.15573663e-02, -8.13295317e-02], [8.96941418e-02, -8.13272578e-02], 

735 [9.73182938e-02, -8.14294047e-02], [1.05133937e-01, -8.16889268e-02], 

736 [1.13212537e-01, -8.20789122e-02], [1.21487501e-01, -8.25701110e-02], 

737 [1.29892236e-01, -8.31332728e-02], [1.38360149e-01, -8.37391475e-02], 

738 [1.46824648e-01, -8.43584849e-02], [1.55219140e-01, -8.49620349e-02], 

739 [1.63477033e-01, -8.55205474e-02], [1.71531735e-01, -8.60047721e-02], 

740 [1.79316652e-01, -8.63854590e-02], [1.87152832e-01, -8.66480710e-02], 

741 [1.95714938e-01, -8.68587711e-02], [2.03988092e-01, -8.70050279e-02], 

742 [2.12037249e-01, -8.70805828e-02], [2.19927361e-01, -8.70791767e-02], 

743 [2.27723383e-01, -8.69945509e-02], [2.35490269e-01, -8.68204465e-02], 

744 [2.43292970e-01, -8.65506046e-02], [2.51196443e-01, -8.61787663e-02], 

745 [2.59265639e-01, -8.56986728e-02], [2.67565512e-01, -8.51040652e-02], 

746 [2.76161016e-01, -8.43886846e-02], [2.84315032e-01, -8.35517227e-02], 

747 [2.92367976e-01, -8.24952891e-02], [3.00378722e-01, -8.12485380e-02], 

748 [3.08356779e-01, -7.98455322e-02], [3.16311653e-01, -7.83203346e-02], 

749 [3.24252851e-01, -7.67070080e-02], [3.32189881e-01, -7.50396152e-02], 

750 [3.40132248e-01, -7.33522191e-02], [3.48089461e-01, -7.16788824e-02], 

751 [3.56071026e-01, -7.00536680e-02], [3.64026861e-01, -6.84887979e-02], 

752 [3.72009305e-01, -6.69046200e-02], [3.80051766e-01, -6.54556124e-02], 

753 [3.88122672e-01, -6.43368550e-02], [3.96190448e-01, -6.37434279e-02], 

754 [4.04340123e-01, -6.37872322e-02], [4.12476471e-01, -6.41239731e-02], 

755 [4.20403940e-01, -6.51405095e-02], [4.28117275e-01, -6.73846014e-02], 

756 [4.35523022e-01, -7.11297084e-02], [4.42484598e-01, -7.53221252e-02], 

757 [4.49115562e-01, -7.98271859e-02], [4.55502974e-01, -8.46869603e-02], 

758 [4.61733900e-01, -8.99435183e-02], [4.67658749e-01, -9.54772245e-02], 

759 [4.73314668e-01, -1.01437536e-01], [4.78657130e-01, -1.07622152e-01], 

760 [4.83476951e-01, -1.14118977e-01], [4.88829477e-01, -1.20095662e-01], 

761 [4.96557440e-01, -1.21699267e-01], [5.00000000e-01, -1.15512690e-01], 

762 [4.98665409e-01, -1.07139467e-01], [4.95396547e-01, -9.99420672e-02], 

763 [4.90643016e-01, -9.32118670e-02], [4.85494221e-01, -8.69406630e-02], 

764 [4.80139213e-01, -8.08541451e-02], [4.74769874e-01, -7.47571744e-02], 

765 [4.69820081e-01, -6.91463092e-02], [4.64751557e-01, -6.43078085e-02], 

766 [4.59059041e-01, -5.97235164e-02], [4.52382076e-01, -5.49860206e-02], 

767 [4.44360207e-01, -4.96879085e-02], [4.41478998e-01, -4.45081546e-02], 

768 [4.42186082e-01, -3.43341453e-02], [4.41285932e-01, -2.62902902e-02], 

769 [4.36671579e-01, -1.97961477e-02], [4.30482679e-01, -1.44337295e-02], 

770 [4.24302435e-01, -9.31069238e-03], [4.18173472e-01, -4.20392632e-03], 

771 [4.11837700e-01, 9.23360322e-04], [4.05352767e-01, 6.03208266e-03], 

772 [3.98776322e-01, 1.10831558e-02], [3.92166014e-01, 1.60374948e-02], 

773 [3.85579490e-01, 2.08560149e-02], [3.79074399e-01, 2.54996310e-02], 

774 [3.73613887e-01, 2.91974775e-02], [3.67336756e-01, 3.27992505e-02], 

775 [3.59583302e-01, 3.68507411e-02], [3.51083120e-01, 4.10070508e-02], 

776 [3.42565805e-01, 4.49232811e-02], [3.34760953e-01, 4.82545334e-02]]), 

777 fin0=np.array([ 

778 [-9.23715076e-02, 1.07240277e-01], [-9.35295965e-02, 1.07594433e-01], 

779 [-9.67256646e-02, 1.08568249e-01], [-1.01542414e-01, 1.10028743e-01], 

780 [-1.07562547e-01, 1.11842936e-01], [-1.14368767e-01, 1.13877847e-01], 

781 [-1.21543774e-01, 1.16000494e-01], [-1.28670272e-01, 1.18077899e-01], 

782 [-1.35330963e-01, 1.19977081e-01], [-1.41134680e-01, 1.21576288e-01], 

783 [-1.46606509e-01, 1.23053436e-01], [-1.52060241e-01, 1.24502551e-01], 

784 [-1.57506075e-01, 1.25921270e-01], [-1.62954205e-01, 1.27307227e-01], 

785 [-1.68414830e-01, 1.28658058e-01], [-1.73898145e-01, 1.29971399e-01], 

786 [-1.79414348e-01, 1.31244885e-01], [-1.84887478e-01, 1.32455496e-01], 

787 [-1.90359489e-01, 1.33335047e-01], [-1.96015001e-01, 1.33209743e-01], 

788 [-2.01162399e-01, 1.31563565e-01], [-2.04627703e-01, 1.28316201e-01], 

789 [-2.07067923e-01, 1.23267049e-01], [-2.08878927e-01, 1.16897283e-01], 

790 [-2.10020541e-01, 1.12297166e-01], [-2.11393373e-01, 1.06917040e-01], 

791 [-2.12954078e-01, 1.01093164e-01], [-2.14659311e-01, 9.51617962e-02], 

792 [-2.16465726e-01, 8.94591952e-02], [-2.18365897e-01, 8.41154074e-02], 

793 [-2.20352206e-01, 7.88099956e-02], [-2.22436308e-01, 7.35689663e-02], 

794 [-2.24659365e-01, 6.84031347e-02], [-2.27062539e-01, 6.33233164e-02], 

795 [-2.29686992e-01, 5.83403267e-02], [-2.32573887e-01, 5.34649810e-02], 

796 [-2.36430031e-01, 4.83943841e-02], [-2.41498676e-01, 4.29607364e-02], 

797 [-2.46187623e-01, 3.83728372e-02], [-2.48885034e-01, 3.58636954e-02], 

798 [-2.48622153e-01, 3.57912618e-02], [-2.46557549e-01, 3.62272274e-02], 

799 [-2.43025387e-01, 3.70044307e-02], [-2.38266996e-01, 3.81013749e-02], 

800 [-2.32523708e-01, 3.94965634e-02], [-2.26036853e-01, 4.11684994e-02], 

801 [-2.19047762e-01, 4.30956865e-02], [-2.11797764e-01, 4.52566278e-02], 

802 [-2.04528191e-01, 4.76298267e-02], [-1.97480374e-01, 5.01937866e-02], 

803 [-1.91394789e-01, 5.27029072e-02], [-1.86459609e-01, 5.49493825e-02], 

804 [-1.81052095e-01, 5.75526666e-02], [-1.75250688e-01, 6.04617194e-02], 

805 [-1.69133831e-01, 6.36255006e-02], [-1.62779966e-01, 6.69929702e-02], 

806 [-1.56267535e-01, 7.05130879e-02], [-1.49674979e-01, 7.41348134e-02], 

807 [-1.43080740e-01, 7.78071067e-02], [-1.36563261e-01, 8.14789275e-02], 

808 [-1.30200984e-01, 8.50992356e-02], [-1.24072349e-01, 8.86169909e-02], 

809 [-1.18255800e-01, 9.19811531e-02], [-1.12829778e-01, 9.51406820e-02], 

810 [-1.07872725e-01, 9.80445375e-02], [-1.03463084e-01, 1.00641679e-01], 

811 [-9.96792947e-02, 1.02881067e-01], [-9.65998008e-02, 1.04711661e-01], 

812 [-9.43030437e-02, 1.06082421e-01], [-9.28674653e-02, 1.06942306e-01]]), 

813 fin1=np.array([ 

814 [-5.63562109e-02, -8.66230690e-02], [-5.80378311e-02, -8.77598862e-02], 

815 [-6.25544177e-02, -9.07828740e-02], [-6.91135601e-02, -9.51108371e-02], 

816 [-7.69228473e-02, -1.00162580e-01], [-8.51898685e-02, -1.05356908e-01], 

817 [-9.31222129e-02, -1.10112625e-01], [-9.99878561e-02, -1.13889019e-01], 

818 [-1.06504731e-01, -1.17311843e-01], [-1.13074811e-01, -1.20683973e-01], 

819 [-1.19721672e-01, -1.23894532e-01], [-1.26468889e-01, -1.26832643e-01], 

820 [-1.33340040e-01, -1.29387427e-01], [-1.40358701e-01, -1.31448008e-01], 

821 [-1.47580880e-01, -1.32990365e-01], [-1.54940053e-01, -1.33335047e-01], 

822 [-1.61577933e-01, -1.30712902e-01], [-1.67054395e-01, -1.26102505e-01], 

823 [-1.71669835e-01, -1.20355834e-01], [-1.75809346e-01, -1.14080721e-01], 

824 [-1.79869801e-01, -1.07847816e-01], [-1.83893833e-01, -1.01567472e-01], 

825 [-1.87727742e-01, -9.52536460e-02], [-1.91491183e-01, -8.89575805e-02], 

826 [-1.95303810e-01, -8.27305179e-02], [-1.99285279e-01, -7.66237008e-02], 

827 [-2.03323939e-01, -7.09497866e-02], [-2.07222716e-01, -6.56608257e-02], 

828 [-2.11321456e-01, -6.03101264e-02], [-2.15707243e-01, -5.49148986e-02], 

829 [-2.20467161e-01, -4.94923522e-02], [-2.25688295e-01, -4.40596970e-02], 

830 [-2.31457727e-01, -3.86341430e-02], [-2.37862543e-01, -3.32328999e-02], 

831 [-2.46515829e-01, -2.68980564e-02], [-2.55762572e-01, -2.13588469e-02], 

832 [-2.63822695e-01, -1.73872025e-02], [-2.69995895e-01, -1.48443106e-02], 

833 [-2.73581870e-01, -1.35913585e-02], [-2.73905506e-01, -1.34429496e-02], 

834 [-2.70916623e-01, -1.39170287e-02], [-2.65183910e-01, -1.49680871e-02], 

835 [-2.57298969e-01, -1.66581465e-02], [-2.47853402e-01, -1.90492292e-02], 

836 [-2.37438812e-01, -2.22033569e-02], [-2.27950178e-01, -2.55768430e-02], 

837 [-2.20118830e-01, -2.83655326e-02], [-2.12826783e-01, -3.08912332e-02], 

838 [-2.05971274e-01, -3.32032068e-02], [-1.99449541e-01, -3.53507153e-02], 

839 [-1.93158823e-01, -3.73830207e-02], [-1.86996359e-01, -3.93493848e-02], 

840 [-1.80859385e-01, -4.12990695e-02], [-1.74645142e-01, -4.32813368e-02], 

841 [-1.68250866e-01, -4.53454486e-02], [-1.61573797e-01, -4.75406669e-02], 

842 [-1.54511172e-01, -4.99162535e-02], [-1.46960230e-01, -5.25214703e-02], 

843 [-1.38818209e-01, -5.54055794e-02], [-1.31057252e-01, -5.82788279e-02], 

844 [-1.23738218e-01, -6.13446244e-02], [-1.16211608e-01, -6.47801054e-02], 

845 [-1.08665309e-01, -6.84191129e-02], [-1.01287211e-01, -7.20954885e-02], 

846 [-9.42652035e-02, -7.56430740e-02], [-8.77871747e-02, -7.88957112e-02], 

847 [-8.20410142e-02, -8.16872418e-02], [-7.72146108e-02, -8.38515077e-02], 

848 [-7.01142594e-02, -8.57539808e-02], [-6.08611143e-02, -8.65416398e-02]]), 

849 fin2=np.array([ 

850 [-4.95709300e-01, 9.71361627e-02], [-4.94727751e-01, 9.40282315e-02], 

851 [-4.92102953e-01, 8.63001401e-02], [-4.89531928e-01, 7.93902959e-02], 

852 [-4.87029725e-01, 7.32981516e-02], [-4.84335965e-01, 6.75182749e-02], 

853 [-4.81551826e-01, 6.25554763e-02], [-4.78127088e-01, 5.76995014e-02], 

854 [-4.74138256e-01, 5.27407642e-02], [-4.69901081e-01, 4.78822911e-02], 

855 [-4.65707580e-01, 4.32915371e-02], [-4.61429843e-01, 3.88748202e-02], 

856 [-4.56778758e-01, 3.47247641e-02], [-4.52133680e-01, 3.06597385e-02], 

857 [-4.47773120e-01, 2.62910115e-02], [-4.43994422e-01, 2.12957780e-02], 

858 [-4.40936734e-01, 1.58644670e-02], [-4.38682055e-01, 1.00694929e-02], 

859 [-4.37395623e-01, 3.93321716e-03], [-4.37251179e-01, -2.22422408e-03], 

860 [-4.38411278e-01, -8.31550780e-03], [-4.40881051e-01, -1.40008006e-02], 

861 [-4.44310154e-01, -1.91401554e-02], [-4.48235249e-01, -2.40147279e-02], 

862 [-4.52186381e-01, -2.88922787e-02], [-4.55951262e-01, -3.38845300e-02], 

863 [-4.59685991e-01, -3.88613661e-02], [-4.63182959e-01, -4.39898598e-02], 

864 [-4.66221839e-01, -4.94607809e-02], [-4.69128507e-01, -5.63647484e-02], 

865 [-4.71915070e-01, -6.41181386e-02], [-4.74263992e-01, -7.12979021e-02], 

866 [-4.75857737e-01, -7.64809898e-02], [-4.76376517e-01, -7.82540679e-02], 

867 [-4.75295478e-01, -7.70124597e-02], [-4.72622968e-01, -7.39633741e-02], 

868 [-4.68700403e-01, -6.95271204e-02], [-4.63869200e-01, -6.41240080e-02], 

869 [-4.58470778e-01, -5.81743460e-02], [-4.52846552e-01, -5.20984438e-02], 

870 [-4.47337939e-01, -4.63166105e-02], [-4.42286358e-01, -4.12491555e-02], 

871 [-4.37409139e-01, -3.64697530e-02], [-4.32541922e-01, -3.13144948e-02], 

872 [-4.27898895e-01, -2.59396949e-02], [-4.23628692e-01, -2.04557516e-02], 

873 [-4.19879947e-01, -1.49730632e-02], [-4.16801293e-01, -9.60202801e-03], 

874 [-4.14541365e-01, -4.45304422e-03], [-4.13248797e-01, 3.63489840e-04], 

875 [-4.13063337e-01, 4.59529287e-03], [-4.14062952e-01, 8.03555956e-03], 

876 [-4.16210151e-01, 1.20244157e-02], [-4.19333841e-01, 1.64554100e-02], 

877 [-4.23262931e-01, 2.12220910e-02], [-4.27826327e-01, 2.62180073e-02], 

878 [-4.32852937e-01, 3.13367077e-02], [-4.38171670e-01, 3.64717406e-02], 

879 [-4.43611431e-01, 4.15166547e-02], [-4.49001130e-01, 4.63649986e-02], 

880 [-4.54169673e-01, 5.09103210e-02], [-4.58945968e-01, 5.50461704e-02], 

881 [-4.65985656e-01, 6.14539934e-02], [-4.72468848e-01, 6.79891568e-02], 

882 [-4.78279615e-01, 7.43791294e-02], [-4.83358777e-01, 8.04000934e-02], 

883 [-4.87647158e-01, 8.58282310e-02], [-4.91085578e-01, 9.04397245e-02], 

884 [-4.93614861e-01, 9.40107561e-02], [-4.95175827e-01, 9.63175081e-02]]), 

885 eye=np.array([0.36, -0.01, 0.015])) 

886"""Outline of an *Gnathonemus petersii* viewed from the side.""" 

887 

888fish_shapes = dict(Alepto_top=Alepto_top, 

889 Alepto_male_side=Alepto_male_side, 

890 Eigenmannia_top=Eigenmannia_top, 

891 Eigenmannia_side=Eigenmannia_side, 

892 Gpetersii_top=Gpetersii_top, 

893 Gpetersii_side=Gpetersii_side) 

894"""Dictionary holding all electric fish shapes.""" 

895 

896fish_top_shapes = dict(Alepto=Alepto_top, 

897 Eigenmannia=Eigenmannia_top, 

898 Gpetersii=Gpetersii_top) 

899"""Dictionary holding electric fish shapes viewed from top.""" 

900 

901fish_side_shapes = dict(Alepto_male=Alepto_male_side, 

902 Eigenmannia=Eigenmannia_side, 

903 Gpetersii=Gpetersii_side) 

904"""Dictionary holding electric fish shapes viewed from the side.""" 

905 

906 

907def fish_shape(fish): 

908 """Get a dictinary containing shapes of a fish. 

909 

910 Parameters 

911 ---------- 

912 fish: string or tuple or dict 

913 Specifies a fish to show: 

914 - any of the strings defining a shape contained in the `fish_shapes` dictionary, 

915 - a tuple with the name of the fish as the first element and 'top' or 'side' as the second element, 

916 - a dictionary with at least a 'body' key holding pathes to be drawn. 

917 

918 Returns 

919 ------- 

920 fish: dict 

921 Dictionary with at least a 'body' key holding pathes to be drawn. 

922 """ 

923 if not isinstance(fish, dict): 

924 if isinstance(fish, (tuple, list)): 

925 if fish[1] == 'top': 

926 fish = fish_top_shapes[fish[0]] 

927 else: 

928 fish = fish_side_shapes[fish[0]] 

929 else: 

930 fish = fish_shapes[fish] 

931 return fish 

932 

933 

934def plot_fish(ax, fish, pos=(0, 0), direction=(1, 0), size=20.0, bend=0, scaley=1, 

935 bodykwargs={}, finkwargs={}, eyekwargs=None): 

936 """Plot body, fins and eye of an electric fish. 

937 

938 Parameters 

939 ---------- 

940 ax: matplotlib axes 

941 Axes where to draw the fish. 

942 fish: string or tuple or dict 

943 Specifies a fish to show: 

944 - any of the strings defining a shape contained in the `fish_shapes` dictionary, 

945 - a tuple with the name of the fish as the first element and 'top' or 'side' as the second element, 

946 - a dictionary with at least a 'body' key holding pathes to be drawn. 

947 pos: tuple of floats 

948 Coordinates of the fish's position (its center). 

949 direction: tuple of floats 

950 Coordinates of a vector defining the orientation of the fish. 

951 size: float 

952 Size of the fish. 

953 bend: float 

954 Bending angle of the fish's tail in degree. 

955 scaley: float 

956 Scale factor applied in y direction after bending and rotation to 

957 compensate for differently scaled axes. 

958 bodykwargs: dict 

959 Key-word arguments for PathPatch used to draw the fish's body. 

960 finkwargs: dict 

961 Key-word arguments for PathPatch used to draw the fish's fins. 

962 

963 Returns 

964 ------- 

965 bpatch: matplotlib.patches.PathPatch 

966 The fish's body. Can be used for set_clip_path(). 

967 

968 Example 

969 ------- 

970 

971 ``` 

972 fig, ax = plt.subplots() 

973 bodykwargs=dict(lw=1, edgecolor='k', facecolor='k') 

974 finkwargs=dict(lw=1, edgecolor='k', facecolor='grey') 

975 fish = (('Eigenmannia', 'side'), (0, 0), (1, 0), 20.0, -25) 

976 plot_fish(ax, *fish, bodykwargs=bodykwargs, finkwargs=finkwargs) 

977 ax.set_xlim(-15, 15) 

978 ax.set_ylim(-10, 10) 

979 plt.show() 

980 ``` 

981 """ 

982 fish = fish_shape(fish) 

983 bpatch = None 

984 size_fac = 1.1 

985 bbox = bbox_pathes(*fish.values()) 

986 trans = mpl.transforms.Affine2D() 

987 angle = np.arctan2(direction[1], direction[0]) 

988 trans.rotate(angle) 

989 #trans.scale(dxu/dyu, dyu/dxu) # what is the right scaling???? 

990 trans.scale(1, scaley) 

991 trans.translate(*pos) 

992 for part, verts in fish.items(): 

993 if part == 'eye': 

994 if eyekwargs is not None: 

995 verts = np.array(verts)*size*size_fac 

996 verts[:2] = trans.transform_point(verts[:2]) 

997 if not 'zorder' in eyekwargs: 

998 eyekwargs['zorder'] = 20 

999 ax.add_patch(Circle(verts[:2], verts[2], **eyekwargs)) 

1000 continue 

1001 verts = bend_path(verts, bend, size, size_fac) 

1002 codes = np.zeros(len(verts)) 

1003 codes[:] = Path.LINETO 

1004 codes[0] = Path.MOVETO 

1005 codes[-1] = Path.CLOSEPOLY 

1006 path = Path(verts, codes) 

1007 #pixelx = np.abs(np.diff(ax.get_window_extent().get_points()[:,0]))[0] 

1008 #pixely = np.abs(np.diff(ax.get_window_extent().get_points()[:,1]))[0] 

1009 #xmin, xmax = ax.get_xlim() 

1010 #ymin, ymax = ax.get_ylim() 

1011 #dxu = np.abs(xmax - xmin)/pixelx 

1012 #dyu = np.abs(ymax - ymin)/pixely 

1013 path = path.transformed(trans) 

1014 kwargs = bodykwargs if part == 'body' else finkwargs 

1015 if not 'zorder' in kwargs: 

1016 kwargs['zorder'] = 0 if part == 'body' else 10 

1017 patch = PathPatch(path, **kwargs) 

1018 if part == 'body': 

1019 bpatch = patch 

1020 ax.add_patch(patch) 

1021 return bpatch 

1022 

1023 

1024def plot_object(ax, pos=(0, 0), radius=1.0, **kwargs): 

1025 """Plot circular object. 

1026 

1027 Parameters 

1028 ---------- 

1029 ax: matplotlib axes 

1030 Axes where to draw the object. 

1031 pos: tuple of floats 

1032 Coordinates of the objects's position (its center). 

1033 radius: float 

1034 Radius of the cirular object. 

1035 kwargs: key word arguments 

1036 Arguments for Circle used to draw the obkect. 

1037 """ 

1038 ax.add_patch(Circle(pos, radius, **kwargs)) 

1039 

1040 

1041def plot_fishfinder(ax, pos, direction, length, handle=0.05, 

1042 central_ground=False, wires=False, 

1043 rodkwargs=dict(edgecolor='none', facecolor='gray'), 

1044 poskwargs=dict(edgecolor='none', facecolor='red'), 

1045 negkwargs=dict(edgecolor='none', facecolor='blue'), 

1046 gndkwargs=dict(edgecolor='none', facecolor='black'), 

1047 lw=1, zorder=50): 

1048 """Plot a fishfinder with electrodes and wires. 

1049 

1050 Parameters 

1051 ---------- 

1052 ax: matplotlib axes 

1053 Axes where to draw the fishfinder. 

1054 pos: tuple of floats 

1055 Coordinates of the fishfinder's position (its center). 

1056 direction: tuple of floats 

1057 Coordinates defining the orientation of the fishfinder. 

1058 length: float 

1059 Length of the fishfinder (center of positive electrode 

1060 minus center of negative electrode). 

1061 handle: float 

1062 Length of handle (rod beyond the negative electrode) 

1063 as a fraction of the `length` of fishfinder. 

1064 central_ground: bool 

1065 Add a central ground electrode. 

1066 wires: bool, 'postop' or 'negtop' 

1067 Draw wires for each electrode. 

1068 - True or 'postop': draw wire of positive electrode on top. 

1069 - 'negtop': draw wire of negative electrode on top. 

1070 Return the coordinates of the endpoints of the wires. 

1071 rodkwargs: dict 

1072 Key-word arguments for Rectangle used to draw the rod. 

1073 poskwargs: dict 

1074 Key-word arguments for Rectangle used to draw the positive electrode. 

1075 negkwargs: dict 

1076 Key-word arguments for Rectangle used to draw the negative electrode. 

1077 gndkwargs: dict 

1078 Key-word arguments for Rectangle used to draw the ground electrode. 

1079 lw: float 

1080 Width of the lines used for drawing the wires. 

1081 zorder: int 

1082 zorder for the fishfinder. 

1083 

1084 Returns 

1085 ------- 

1086 negpos: tuple of floats 

1087 Coordinates of center of negative electrode. 

1088 pospos: tuple of floats 

1089 Coordinates of center of positive electrode. 

1090 negwirepos: tuple of floats 

1091 If `wire`, the end of the wire of the negative electrode. 

1092 poswirepos: tuple of floats 

1093 If `wire`, the end of the wire of the positive electrode. 

1094 gndwirepos: tuple of floats 

1095 If `central_ground` and `wire`, the end of the wire of 

1096 the ground electrode. 

1097 """ 

1098 width = 0.07*length 

1099 transform = mpt.Affine2D().rotate(np.arctan2(direction[1], direction[0])).translate(*pos) 

1100 

1101 ax.add_patch(Rectangle((-(0.5+handle)*length, -0.5*width), 

1102 (1+handle+0.05)*length, width, 

1103 transform=transform + ax.transData, 

1104 zorder=zorder, **rodkwargs)) 

1105 ax.add_patch(Rectangle((0.5*length-0.4*width, -0.6*width), 

1106 0.8*width, 1.2*width, 

1107 transform=transform + ax.transData, 

1108 zorder=zorder+2, **poskwargs)) 

1109 ax.add_patch(Rectangle((-0.5*length-0.4*width, -0.6*width), 

1110 0.8*width, 1.2*width, 

1111 transform=transform + ax.transData, 

1112 zorder=zorder+2, **negkwargs)) 

1113 nodes = [(-0.5*length, 0), (0.5*length, 0)] 

1114 if central_ground: 

1115 ax.add_patch(Rectangle((-0.4*width, -0.6*width), 

1116 0.8*width, 1.2*width, 

1117 transform=transform + ax.transData, 

1118 zorder=zorder+2, **gndkwargs)) 

1119 if wires: 

1120 offs = 0.03*width*lw 

1121 if wires == 'negtop': 

1122 offs *= -1 

1123 if central_ground: 

1124 offs *= 2 

1125 color = negkwargs.get('facecolor') 

1126 ax.plot((-0.5*length, -(0.5+handle)*length), (-offs, -offs), 

1127 color=color, lw=lw, solid_capstyle='butt', 

1128 transform=transform + ax.transData, zorder=zorder+1) 

1129 color = poskwargs.get('facecolor') 

1130 ax.plot((0.5*length, -(0.5+handle)*length), (offs, offs), 

1131 color=color, lw=lw, solid_capstyle='butt', transform=transform + 

1132 ax.transData, zorder=zorder+1) 

1133 nodes.extend(((-(0.5+handle)*length, -offs), (-(0.5+handle)*length, offs))) 

1134 if central_ground: 

1135 color = gndkwargs.get('facecolor') 

1136 ax.plot((0, -(0.5+handle)*length), (0, 0), 

1137 color=color, lw=lw, solid_capstyle='butt', 

1138 transform=transform + ax.transData, zorder=zorder+1) 

1139 nodes.append((-(0.5+handle)*length, 0)) 

1140 nodes = transform.transform(nodes) 

1141 return nodes 

1142 

1143 

1144def plot_pathes(ax, *vertices, **kwargs): 

1145 """Plot pathes. 

1146 

1147 Parameters 

1148 ---------- 

1149 ax: matplotlib axes 

1150 Axes where to draw the path. 

1151 vertices: one or more 2D arrays 

1152 The coordinates of pathes to be plotted 

1153 (first column x-coordinates, second colum y-coordinates). 

1154 kwargs: key word arguments 

1155 Arguments for PathPatch used to draw the path. 

1156 """ 

1157 for verts in vertices: 

1158 codes = np.zeros(len(verts)) 

1159 codes[:] = Path.LINETO 

1160 codes[0] = Path.MOVETO 

1161 codes[-1] = Path.CLOSEPOLY 

1162 path = Path(verts, codes) 

1163 ax.add_patch(PathPatch(path, **kwargs)) 

1164 bbox = bbox_pathes(*vertices) 

1165 center = np.mean(bbox, axis=0) 

1166 bbox -= center 

1167 bbox *= 1.2 

1168 bbox += center 

1169 ax.set_xlim(*bbox[:,0]) 

1170 ax.set_ylim(*bbox[:,1]) 

1171 

1172 

1173def fish_surface(fish, pos=(0, 0), direction=(1, 0), size=20.0, bend=0, 

1174 gamma=1.0): 

1175 """Generate meshgrid of one side of the fish from shape. 

1176  

1177 Parameters 

1178 ---------- 

1179 fish: string or tuple or dict 

1180 Specifies a fish to show: 

1181 - any of the strings defining a shape contained in the `fish_shapes` dictionary, 

1182 - a tuple with the name of the fish and 'top' or 'side', 

1183 - a dictionary with at least a 'body' key holding pathes to be drawn. 

1184 pos: tuple of floats 

1185 Coordinates of the fish's position (its center). 

1186 direction: tuple of floats 

1187 Coordinates of a vector defining the orientation of the fish. 

1188 size: float 

1189 Size of the fish. 

1190 bend: float 

1191 Bending angle of the fish's tail in degree. 

1192 gamma: float 

1193 Gamma distortion of the ellipse. The ellipse equation is raised 

1194 to the power of gamma before its smaller diameter is scaled up 

1195 from one to the actual value. 

1196 

1197 Returns 

1198 ------- 

1199 xx: 2D array of floats 

1200 x-coordinates in direction of body axis. 

1201 yy: 2D array of floats 

1202 y-coordinates in direction upwards from body axis. 

1203 zz: 2D array of floats 

1204 z-coordinates of fish surface, outside of fish NaN. 

1205 """ 

1206 if direction[1] != 0: 

1207 raise ValueError('rotation not supported by fish_surface yet.') 

1208 fish = fish_shape(fish) 

1209 bbox = bbox_pathes(*fish.values()) 

1210 size_fac = -1.05*0.5/bbox[0,0] 

1211 path = bend_path(fish['body'], bend, size, size_fac) 

1212 # split in top and bottom half: 

1213 minxi = np.argmin(path[:,0]) 

1214 maxxi = np.argmax(path[:,0]) 

1215 i0 = min(minxi, maxxi) 

1216 i1 = max(minxi, maxxi) 

1217 path0 = path[i0:i1,:] 

1218 path1 = np.vstack((path[i0::-1,:], path[:i1:-1,:])) 

1219 if np.mean(path0[:,1]) < np.mean(path1[:,1]): 

1220 path0, path1 = path1, path0 

1221 # make sure x coordinates are monotonically increasing: 

1222 pm = np.maximum.accumulate(path0[:,0]) 

1223 path0 = np.delete(path0, np.where(path0[:,0] < pm)[0], axis=0) 

1224 pm = np.maximum.accumulate(path1[:,0]) 

1225 path1 = np.delete(path1, np.where(path1[:,0] < pm)[0], axis=0) 

1226 # rotate: XXX 

1227 # translate: 

1228 minx = path[minxi,0] + pos[0] 

1229 maxx = path[maxxi,0] + pos[0] 

1230 path0 += pos[:2] 

1231 path1 += pos[:2] 

1232 # interpolate: 

1233 n = 5*max(len(path0), len(path1)) 

1234 #n = 200 

1235 x = np.linspace(minx, maxx, n) 

1236 upperpath = np.zeros((len(x), 2)) 

1237 upperpath[:,0] = x 

1238 upperpath[:,1] = np.interp(x, path0[:,0], path0[:,1]) 

1239 lowerpath = np.zeros((len(x), 2)) 

1240 lowerpath[:,0] = x 

1241 lowerpath[:,1] = np.interp(x, path1[:,0], path1[:,1]) 

1242 # ellipse origin and semi axes: 

1243 midline = np.array(upperpath) 

1244 midline[:,1] = np.mean(np.vstack((upperpath[:,1], lowerpath[:,1])), axis=0) 

1245 diamy = upperpath[:,1] - midline[:,1] 

1246 diamz = 0.3*diamy # take it from the top view! 

1247 # apply ellipse: 

1248 y = np.linspace(np.min(midline[:,1]-diamy), np.max(midline[:,1]+diamy), n//2) 

1249 xx, yy = np.meshgrid(x ,y) 

1250 zz = diamz * (np.sqrt(1.0 - ((yy-midline[:,1])/diamy)**2))**gamma 

1251 return xx, yy, zz 

1252 

1253 

1254def surface_normals(xx, yy, zz): 

1255 """Normal vectors on a surface. 

1256 

1257 Compute surface normals on a surface as returned by `fish_surface()`. 

1258 

1259 Parameters 

1260 ---------- 

1261 xx: 2D array of floats 

1262 Mesh grid of x coordinates. 

1263 yy: 2D array of floats 

1264 Mesh grid of y coordinates. 

1265 zz: 2D array of floats 

1266 z-coordinates of surface on the xx and yy coordinates. 

1267 

1268 Returns 

1269 ------- 

1270 nx: 2D array of floats 

1271 x-coordinates of normal vectors for each point in xx and yy. 

1272 ny: 2D array of floats 

1273 y-coordinates of normal vectors for each point in xx and yy. 

1274 nz: 2D array of floats 

1275 z-coordinates of normal vectors for each point in xx and yy. 

1276 """ 

1277 dx = xx[0,1] - xx[0,0] 

1278 dy = yy[1,0] - yy[0,0] 

1279 nx = np.zeros(xx.shape) 

1280 nx[:,:-1] = -np.diff(zz, axis=1)/dx 

1281 ny = np.zeros(xx.shape) 

1282 ny[:-1,:] = -np.diff(zz, axis=0)/dy 

1283 nz = np.ones(xx.shape) 

1284 norm = np.sqrt(nx*nx+ny*ny+1) 

1285 return nx/norm, ny/norm, nz/norm 

1286 

1287 

1288def extract_path(svgfile, path_index, npoints): 

1289 """Convert SVG pathes to numpy array with path coordinates. 

1290 

1291 Draw a fish outline in inkscape and save it to a svg file. 

1292 

1293 Install the svgpathtools package 

1294 (https://github.com/mathandy/svgpathtools): 

1295 ``` 

1296 pip install svgpathtools 

1297 ``` 

1298  

1299 Parameters 

1300 ---------- 

1301 svgfile: string 

1302 Name of the svg file containing the path. 

1303 path_index: int 

1304 Index selecting the path. 

1305 npoints: int 

1306 Number of points to spread out on the path. 

1307 

1308 Returns 

1309 ------- 

1310 vertices: 2D array 

1311 The coordinates of the outline of a fish. 

1312 npoints rows of x and y coordinates. 

1313 """ 

1314 from svgpathtools import svg2paths2 

1315 

1316 paths, attributes, svg_attributes = svg2paths2(svgfile) 

1317 path = paths[path_index] 

1318 vertices = np.zeros((npoints, 2)) 

1319 for i in range(npoints): 

1320 p = path.point(i/npoints) 

1321 vertices[i, 0] = p.real 

1322 vertices[i, 1] = p.imag 

1323 return vertices 

1324 

1325 

1326def bbox_pathes(*vertices): 

1327 """Common bounding box of pathes. 

1328 

1329 Parameters 

1330 ---------- 

1331 vertices: one or more 2D arrays 

1332 The coordinates of pathes 

1333 (first column x-coordinates, second colum y-coordinates). 

1334 

1335 Returns 

1336 ------- 

1337 bbox: 2D array 

1338 Bounding box of the pathes: [[x0, y0], [x1, y1]] 

1339 """ 

1340 # get bounding box of all pathes: 

1341 bbox = np.zeros((2, 2)) 

1342 first = True 

1343 for verts in vertices: 

1344 if len(verts.shape) != 2: 

1345 continue 

1346 vbbox = np.array([[np.min(verts[:,0]), np.min(verts[:,1])], 

1347 [np.max(verts[:,0]), np.max(verts[:,1])]]) 

1348 if first: 

1349 bbox = vbbox 

1350 first = False 

1351 else: 

1352 bbox[0,0] = min(bbox[0,0], vbbox[0,0]) 

1353 bbox[0,1] = min(bbox[0,1], vbbox[0,1]) 

1354 bbox[1,0] = max(bbox[1,0], vbbox[1,0]) 

1355 bbox[1,1] = max(bbox[1,1], vbbox[1,1]) 

1356 return bbox 

1357 

1358 

1359def translate_pathes(dx, dy, *vertices): 

1360 """Translate pathes in place. 

1361 

1362 Parameters 

1363 ---------- 

1364 dx: float 

1365 Shift in x direction. 

1366 dy: float 

1367 Shift in y direction. 

1368 vertices: one or more 2D arrays 

1369 The coordinates of pathes to be translated 

1370 (first column x-coordinates, second colum y-coordinates). 

1371 """ 

1372 for verts in vertices: 

1373 verts[:,0] += dx 

1374 verts[:,1] += dy 

1375 

1376 

1377def center_pathes(*vertices): 

1378 """Translate pathes to their common origin in place. 

1379 

1380 Parameters 

1381 ---------- 

1382 vertices: one or more 2D arrays 

1383 The coordinates of pathes to be centered 

1384 (first column x-coordinates, second colum y-coordinates). 

1385 """ 

1386 center = np.mean(bbox_pathes(*vertices), axis=1) 

1387 # shift: 

1388 for verts in vertices: 

1389 verts[:,0] -= center[0] 

1390 verts[:,1] -= center[1] 

1391 

1392 

1393def rotate_pathes(theta, *vertices): 

1394 """Rotate pathes in place. 

1395 

1396 Parameters 

1397 ---------- 

1398 theta: float 

1399 Rotation angle in degrees. 

1400 vertices: one or more 2D arrays 

1401 The coordinates of pathes to be rotated 

1402 (first column x-coordinates, second colum y-coordinates). 

1403 """ 

1404 theta *= np.pi/180.0 

1405 # rotation matrix: 

1406 c = np.cos(theta) 

1407 s = np.sin(theta) 

1408 rm = np.array(((c, -s), (s, c))) 

1409 # rotation: 

1410 for verts in vertices: 

1411 verts[:,:] = np.dot(verts, rm) 

1412 

1413 

1414def flipx_pathes(*vertices): 

1415 """Flip pathes in x-direction in place. 

1416 

1417 Parameters 

1418 ---------- 

1419 vertices: one or more 2D arrays 

1420 The coordinates of pathes to be flipped 

1421 (first column x-coordinates, second colum y-coordinates). 

1422 """ 

1423 for verts in vertices: 

1424 verts[:,0] = -verts[:,0] 

1425 

1426 

1427def flipy_pathes(*vertices): 

1428 """Flip pathes in y-direction in place. 

1429 

1430 Parameters 

1431 ---------- 

1432 vertices: one or more 2D arrays 

1433 The coordinates of pathes to be flipped 

1434 (first column x-coordinates, second colum y-coordinates). 

1435 """ 

1436 for verts in vertices: 

1437 verts[:,1] = -verts[:,1] 

1438 

1439 

1440def mirror_path(vertices1): 

1441 """Complete path of half a fish outline by appending the mirrored path. 

1442 

1443 It is sufficient to draw half of a top view of a fish. Import with 

1444 extract_path() and use this function to add the missing half of the 

1445 outline to the path. The outline is mirrored on the x-axis. 

1446 

1447 Parameters 

1448 ---------- 

1449 vertices1: 2D array 

1450 The coordinates of one half of the outline of a fish 

1451 (first column x-coordinates, second colum y-coordinates). 

1452 

1453 Returns 

1454 ------- 

1455 vertices: 2D array 

1456 The coordinates of the complete outline of a fish. 

1457 """ 

1458 vertices2 = np.array(vertices1[::-1,:]) 

1459 vertices2[:,1] *= -1 

1460 vertices = np.concatenate((vertices1, vertices2)) 

1461 return vertices 

1462 

1463 

1464def normalize_path(*vertices): 

1465 """Normalize and shift path in place. 

1466 

1467 The path extent in x direction is normalized to one and its center 

1468 is shifted to the origin. 

1469 

1470 Parameters 

1471 ---------- 

1472 vertices: one or more 2D arrays 

1473 The coordinates of the outline of a fish 

1474 (first column x-coordinates, second colum y-coordinates). 

1475 """ 

1476 bbox = bbox_pathes(*vertices) 

1477 for verts in vertices: 

1478 verts[:,1] -= np.mean(bbox[:,1]) 

1479 verts[:,0] -= bbox[0,0] 

1480 verts /= bbox[1,0] - bbox[0,0] 

1481 verts[:,0] -= 0.5 

1482 

1483 

1484def bend_path(path, bend, size, size_fac=1.0): 

1485 """Bend and scale a path. 

1486 

1487 Parameters 

1488 ---------- 

1489 path: 2D array 

1490 The coordinates of a path. 

1491 bend: float 

1492 Angle for bending in degrees. 

1493 size: float 

1494 Scale path to this size. 

1495 size_fac: float 

1496 Scale path even more, but keep size for calculating the bending. 

1497 

1498 Returns 

1499 ------- 

1500 path: 2D array 

1501 The coordinates of the bent and scaled path. 

1502 """ 

1503 path = np.array(path) 

1504 path *= size_fac*size 

1505 if np.abs(bend) > 1.e-8: 

1506 sel = path[:,0]<0.0 

1507 xp = path[sel,0] # all negative x coordinates of path 

1508 yp = path[sel,1] # y coordinates of all negative x coordinates of path 

1509 r = -180.0*0.5*size/bend/np.pi # radius of circle on which to bend the tail 

1510 beta = xp/r # angle on circle for each y coordinate 

1511 R = r-yp # radius of point 

1512 path[sel,0] = -np.abs(R*np.sin(beta)) # transformed x coordinates 

1513 path[sel,1] = r-R*np.cos(beta) # transformed y coordinates 

1514 return path 

1515 

1516 

1517def export_path(vertices): 

1518 """Print coordinates of path for import as numpy array. 

1519 

1520 The variable name, a leading 'np.array([' and the closing '])' 

1521 are not printed. 

1522 

1523 Parameters 

1524 ---------- 

1525 vertices: 2D array 

1526 The coordinates of the path 

1527 (first column x-coordinates, second colum y-coordinates). 

1528 """ 

1529 n = 2 

1530 for k, v in enumerate(vertices): 

1531 if k%n == 0: 

1532 print(' ', end='') 

1533 print(' [%.8e, %.8e],' % (v[0], v[1]), end='') 

1534 if k%n == n-1 and k < len(vertices)-1: 

1535 print('') 

1536 

1537 

1538def export_fish(name, body, *fins): 

1539 """Serialize coordinates of fish outlines as a dictionary. 

1540 

1541 Writes a dictionary with name 'name' and keys 'body', 'fin0', 'fin1', ... 

1542 holding the pathes. 

1543 

1544 Copy these coordinates from the console and paste them into this module. 

1545 Give it a proper name and don't forget to add it to the fish_shapes dictionary 

1546 to make it know to plot_fish(). 

1547 

1548 Parameters 

1549 ---------- 

1550 name: string 

1551 Name of the variable. 

1552 body: 2D array 

1553 The coordinates of fish's body 

1554 (first column x-coordinates, second colum y-coordinates). 

1555 fins: zero or more 2D arrays 

1556 The coordinates of the fish's fins 

1557 (first column x-coordinates, second colum y-coordinates). 

1558 

1559 Returns 

1560 ------- 

1561 fish: dict 

1562 A dictionary holding the pathes that can be passed directly to plot_fish(). 

1563 """ 

1564 print('%s = dict(body=np.array([' % name) 

1565 export_path(body) 

1566 fish = dict(body=body) 

1567 for k, f in enumerate(fins): 

1568 print(']),') 

1569 print(' fin%d=np.array([' % k) 

1570 export_path(f) 

1571 fish['fin%d' % k] = f 

1572 print(']))') 

1573 return fish 

1574 

1575 

1576def export_fish_demo(): 

1577 """Code demonstrating how to export a fish outline from SVG file. 

1578 """ 

1579 body = extract_path('fish.svg', 0, 300) 

1580 fin0 = extract_path('fish.svg', 1, 70) 

1581 fin1 = extract_path('fish.svg', 2, 70) 

1582 verts = (body, fin0, fin1) 

1583 # look at the path: 

1584 fig, ax = plt.subplots() 

1585 plot_pathes(ax, *verts) 

1586 ax.set_aspect('equal') 

1587 plt.show() 

1588 # fix path: 

1589 center_pathes(*verts) 

1590 rotate_pathes(-90.0, *verts) 

1591 #verts[:,1] *= 0.8 # change aspect ratio 

1592 #verts = verts[1:,:] # remove first point 

1593 #translate_pathes(0.0, -np.min(verts[:,1]), verts) 

1594 # mirror, normalize and export path: 

1595 #verts = mirror_path(verts) 

1596 normalize_path(*verts) 

1597 fish = export_fish('fish_side', *verts) 

1598 # plot outline: 

1599 fig, ax = plt.subplots() 

1600 plot_fish(ax, fish, size=1.0/1.1, 

1601 bodykwargs=dict(lw=1, edgecolor='k', facecolor='r'), 

1602 finkwargs=dict(lw=1, edgecolor='k', facecolor='b')) 

1603 ax.set_xlim(-1, 1) 

1604 ax.set_ylim(-0.5, 0.5) 

1605 plt.show() 

1606 

1607 

1608def main(): 

1609 """Plot some fish shapes and surface normals. 

1610 """ 

1611 bodykwargs = dict(lw=1, edgecolor='k', facecolor='none') 

1612 finkwargs = dict(lw=1, edgecolor='k', facecolor='grey') 

1613 eyekwargs = dict(lw=1, edgecolor='white', facecolor='grey') 

1614 var = ['zz', 'nx', 'ny', 'nz'] 

1615 fig, ax = plt.subplots() 

1616 for k in range(4): 

1617 y = (1.5-k)*9 

1618 fish = (('Alepto_male', 'side'), (0, y), (1, 0), 20.0, 0) 

1619 xx, yy, zz = fish_surface(*fish, gamma=0.5) 

1620 nx, ny, nz = surface_normals(xx, yy, zz) 

1621 a = [zz, nx, ny, nz] 

1622 th = np.nanmax(np.abs(a[k])) 

1623 ax.contourf(xx[0,:], yy[:,0], -a[k], 20, vmin=-th, vmax=th, cmap='RdYlBu') 

1624 plot_fish(ax, *fish, bodykwargs=bodykwargs, finkwargs=finkwargs, eyekwargs=eyekwargs) 

1625 ax.text(-11, y+2, var[k]) 

1626 fish = (('Alepto_male', 'side'), (20, -9), (1, 0), 23.0, 10) 

1627 xx, yy, zz = fish_surface(*fish, gamma=0.8) 

1628 nv = surface_normals(xx, yy, zz) 

1629 ilumn = [-0.05, 0.1, 1.0] 

1630 dv = np.zeros(nv[0].shape) 

1631 for nc, ic in zip(nv, ilumn): 

1632 dv += nc*ic 

1633 #ax.contourf(xx[0,:], yy[:,0], dv, 20, cmap='gist_gray') 

1634 ax.contourf(xx[0,:], yy[:,0], dv, levels=[np.nanmin(dv), np.nanmin(dv)+0.99*(np.nanmax(dv)-np.nanmin(dv)), np.nanmax(dv)], cmap='gist_gray') 

1635 plot_fish(ax, *fish, bodykwargs=bodykwargs, finkwargs=finkwargs, eyekwargs=eyekwargs) 

1636 bodykwargs = dict(lw=1, edgecolor='k', facecolor='k') 

1637 fish = (('Alepto', 'top'), (23, 0), (2, 1), 16.0, 25) 

1638 plot_fish(ax, *fish, bodykwargs=bodykwargs, finkwargs=finkwargs) 

1639 fish = (('Eigenmannia', 'top'), (23, 8), (1, 0.3), 16.0, -15) 

1640 plot_fish(ax, *fish, bodykwargs=bodykwargs, finkwargs=finkwargs) 

1641 fish = (('Eigenmannia', 'side'), (20, 18), (1, 0), 20.0, -25) 

1642 plot_fish(ax, *fish, bodykwargs=bodykwargs, finkwargs=finkwargs, eyekwargs=eyekwargs) 

1643 plot_fishfinder(ax, (38, 13), (1, 2), 18, handle=0.2, 

1644 central_ground=True, wires=True, lw=2) 

1645 plot_fishfinder(ax, (38, -8), (1, 2), 18, central_ground=False) 

1646 ax.set_xlim(-15, 45) 

1647 ax.set_ylim(-20, 24) 

1648 ax.set_aspect('equal') 

1649 plt.show() 

1650 

1651 

1652if __name__ == '__main__': 

1653 #export_fish_demo() 

1654 main() 

1655