Skip to content

Commit

Permalink
Remove R charts from default layouts
Browse files Browse the repository at this point in the history
SS-RR and Tri Mix replaced by Python versions
contributed by Fe at the users forum.
The intention is to avoid triggering #4267
  • Loading branch information
amtriathlon committed Sep 5, 2022
1 parent 7d7ed5c commit cc6738b
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 44 deletions.
8 changes: 4 additions & 4 deletions src/Resources/xml/analysis-perspectives.xml
Expand Up @@ -855,17 +855,17 @@
<property name="bin" type="double" value="1" />
<property name="useSelected" type="int" value="0" />
</chart>
<chart id="38" name="" title="SS-SR (Requires R)" >
<property name="title" type="QString" value="SS-SR (Requires R)" />
<chart id="43" name="" title="SS-SR" >
<property name="title" type="QString" value="SS-SR" />
<property name="subtitle" type="QString" value="" />
<property name="widthFactor" type="double" value="2" />
<property name="heightFactor" type="double" value="2" />
<property name="style" type="int" value="0" />
<property name="resizable" type="bool" value="0" />
<property name="script" type="QString" value="## R-chart script.\n## For use with GoldenCheetah.\n## tested on GC.version() is &quot;DEV-V3.5 1705&quot;\n##\nxtext&lt;-&quot;Pace/100m (min:sec)&quot;\nytext&lt;-&quot;Stroke Rate/min (srm)&quot;\n\npushoff&lt;-3 ## push-off compensation (m)\nstrokestyle&lt;-1## 1=freestyle, 2=backstroke, 3=breaststroke, 4=butterfly\n## plot colors\nregionlowfill&lt;-adjustcolor(&quot;#5076a3&quot;,alpha.f=.6)\nregionlowborder&lt;-&quot;#5076a3&quot;\nregionhighfill&lt;-adjustcolor(&quot;#a34b49&quot;,alpha.f=.6)\nregionhighborder&lt;-&quot;#a34b49&quot;\nsb_size_min&lt;-1\nsb_size_max&lt;-15\nsb_alpha&lt;-0.5\n## plot symbols\npl25&lt;-21\npl50&lt;-22\nplx&lt;-23\n#plot limits\nxmin&lt;-130\nxmax&lt;-60\nymin&lt;-30\nymax&lt;-100\n\ndarken &lt;- function(color, factor=1.4){\n col &lt;- col2rgb(color)\n col &lt;- col/factor\n col &lt;- rgb(t(col), maxColorValue=255)\n}\n\nstroketext&lt;-list(&quot;Freestyle&quot;, &quot;Backstroke&quot;, &quot;Breaststroke&quot;, &quot;Butterfly&quot;)\nheader&lt;-paste(stroketext[strokestyle],&quot; stroke rate chart&quot;)\n\n## plot\npar(mar=c(6,6,3,0))\nplot(NULL,NULL, xlim=c(xmin,xmax),ylim=c(ymin,ymax), type=&quot;n&quot;,xlab=&quot;&quot;,ylab=&quot;&quot;, xaxt=&quot;n&quot;, yaxt=&quot;n&quot;)\n## ticks\nat=seq(xmin,xmax,-10)\naxis(1, at=at, tcl=-0.8, labels=sprintf(&quot;%d:%02d&quot;,at%/%60,at%%60))##major x-axis\naxis(1, at=seq(xmin,xmax,-1), labels=NA)##minor x-axis\naxis(2, at=seq(ymin,ymax,10), tcl=-0.8, las=2)##major y-axis\naxis(2, at=seq(ymin,ymax,1), labels=NA)##minor y-axis\n\n## region low\n##lines(x_region1,region_low,type=&quot;l&quot;, col=&quot;blue&quot;)\nx_region1&lt;- c(130 ,120 ,110 ,100 ,90 ,80 ,70 ,60)\nregion_low&lt;-c(50.0,50.8,51.6,53.0,54.5,57.0,61.0,67.0)\npolygon(c(xmin,x_region1,xmax),c(ymin,region_low,ymin),col=regionlowfill,border=regionlowborder)\n##text(127,31,&quot;Low Stroke rate&quot;, col=&quot;#0000FF&quot;, cex=1)\nmtext(&quot;Low Stroke rate&quot;,1, line=-3.5, col=&quot;#0000FF&quot;, cex=1)\n\n## region high\n##lines(x_region2,region_high,type=&quot;l&quot;, col=&quot;red&quot;)\nx_region2&lt;- c(130 ,120 ,110 ,100 ,95.5,90 ,80 ,70 ,67)\nregion_high&lt;-c(61.8,63.4,65.2,68.0,70.0,73.1,83.1,96.0,100.0)\npolygon(c(xmin,x_region2),c(ymax,region_high),col=regionhighfill,border=regionhighborder)\n##text(126.9,99,&quot;High Stroke rate&quot;, col=&quot;#ff0000&quot;, cex=1)\nmtext(&quot;High Stroke rate&quot;,3, line=-3.5, col=&quot;#ff0000&quot;, cex=1)\n\n## region OK\n##polygon(c(x_region1,rev(c(x_region2,xmax))),c(region_low,rev(c(region_high,ymax))),col=&quot;gray&quot;,border=&quot;gray&quot;)\n\n## title\ntitle(main=header,cex.main=2.0,xlab=xtext,ylab=ytext)\n\n## grid lines\ngrid(col=&quot;#606060&quot;, lty=&quot;solid&quot;, lwd=0.5)\n\n## plot values, use available swim data(XDATA)\nmetrics&lt;-GC.activity.metrics(compare=TRUE)\nactivities&lt;-GC.activity(compare=TRUE)\nfor(a in 1:length(activities)){\n if (&quot;SWIM_TYPE&quot; %in% names(activities[[a]]$activity))##swim activity?\n {\n swim&lt;-activities[[a]]$activity[which(as.numeric(activities[[a]]$activity$SWIM_TYPE)==strokestyle),]\n if (&quot;Pool_Length&quot; %in% names(metrics[[a]]$metrics)){Pool_Length&lt;-as.numeric(metrics[[a]]$metrics$Pool_Length)}else{Pool_Length&lt;-0}\n pointfill&lt;-activities[[a]]$color\n pointfill&lt;-adjustcolor(activities[[a]]$color,alpha.f=sb_alpha)\n pointborder&lt;-darken(activities[[a]]$color)\n\n if (Pool_Length==25){sb1&lt;-pl25}\n else {if (Pool_Length==50){sb1&lt;-pl50}\n else {sb1&lt;-plx}}\n\n pace&lt;-swim$SWIM_DURATION*100/Pool_Length\n sr&lt;-(60*2*swim$SWIM_STROKES/swim$SWIM_DURATION)/(1-pushoff/Pool_Length)## 2arms per minute, incl pushoff compensation\n ##lines(pace, sr, type=&quot;p&quot;, col=pointborder, bg=pointfill, pch=sb1, cex=pointsize)\n pl&lt;-lowess(round(pace),sr)\n xn&lt;-table(pl$x)\n f&lt;-xn/max(xn)\n lines(pl$x[!duplicated(pl$x)],pl$y[!duplicated(pl$x)], type=&quot;o&quot;, col=pointborder, bg=pointfill, pch=sb1, cex=sb_size_min+(sb_size_max-sb_size_min)*f)\n }\n}\nlegend(&quot;top&quot;, legend=c(&quot;25m&quot;,&quot;50m&quot;,&quot;custom&quot;), pch=c(pl25,pl50,plx), horiz=TRUE, bty=&quot;n&quot;, xpd=TRUE, inset=c(0), pt.cex=2)\n" />
<property name="script" type="QString" value="## R (Daimon) -&gt; Python (Fe)\n##.....................................................\n##.....................................................\n##\n## R script\n## Chart: SS-SR\n## Creator: Daimon\n##\n## For use with GoldenCheetah\n## tested on GC.version() is &quot;DEV-V3.5 1705&quot;\n##\n\n## SS-SR\n## Last Edited At: 2017-09-26 - Creator: Daimon\n## This stroke rate chart is combined with the SwimSmooth preferde (optimal) zones for freestyle swimming.\n\n## This chart displays the (combined lowess) strokerate on the x-axis versus the pace on the y-axis.\n\n## The script expects Garmin values for the Strokestyle. (1=freestyle, 2=backstroke, 3=breaststroke, 4=butterfly)\n\n## It takes into account a 3m push-off per length/lane.\n## You can change this value in the script at &quot;pushoff&lt;-3 ## push-off compensation (m)&quot;\n## The type of stroke can be change in the script at &quot;strokestyle&lt;-1## 1=freestyle, 2=backstroke, 3=breaststroke, 4=butterfly&quot; but the defined strokerate areas are SwimSmooth Freestyle zones!\n\n## There are simulair R-chart scripts available in the repository - this script is my interpretation and uses the available swim metrics - it&apos;s a matter of preference which script to use.\n\n## Since no default value is defined for Pool Length there is a prerequisite.\n## (If Pool Length is not available no strokerate nor pace will be calculated)\n\n## Prerequisite:\n## check in the menu under Tools-&gt;Options select the Datafields tab\n## for the presence/definition of the DataField &quot;Pool Length&quot; .\n\n## if not: in the Menu under Tools-&gt;Options select the Datafields tab\n## select &quot;+&quot; and edit the created row to &quot; Workout&quot;, &quot;Pool Length&quot; ,&quot;Double&quot;\n\n## In the legenda &quot;custom&quot; indicates a pool length not exactly 25m or 50m\n\n## http://www.swimsmooth.com/strokerate.html\n\n##.....................................................\n##\n## Python script\n## Chart: Py_SS-SR_04\n## Creator: Fe \n##\n## GC.version() &quot;V3.6-RC1&quot; (Build id: 4010 2022/07/04)\n##\n## 08&apos;2022\n## Python Script \n##\n## Python: 3.7.9 (Aug 17 2020)\n## Plotly: 4.6.0 --&gt; 5.2.1\n## Test: GarminSwimExample_2015_11_05_18_45_42.fit\n##\n## Golden Cheetah: &quot;V3.6-RC1&quot; (Build id: 4010 2022/07/04)\n## Activities\n##\n## Note: add marker symbol (25 circle, 50 square, custom diamond -&gt; sb1) (trace_sm_lowess)\n##\n##.....................................................\n\n## packages\n#import pandas as pd\nimport plotly as ply\nimport plotly.express as px\nimport plotly.graph_objs as go\nimport numpy as np\nimport datetime\nimport tempfile\nimport pathlib\n\n#......................................................\n\n#&quot;&quot;&quot;\n#This module implements the Lowess function for nonparametric regression.\n#Functions:\n#lowess Fit a smooth nonparametric regression curve to a scatterplot.\n#For more information, see\n#William S. Cleveland: &quot;Robust locally weighted regression and smoothing\n#scatterplots&quot;, Journal of the American Statistical Association, December 1979,\n#volume 74, number 368, pp. 829-836.\n#William S. Cleveland and Susan J. Devlin: &quot;Locally weighted regression: An\n#approach to regression analysis by local fitting&quot;, Journal of the American\n#Statistical Association, September 1988, volume 83, number 403, pp. 596-610.\n#&quot;&quot;&quot;\n# Authors: Alexandre Gramfort &lt;alexandre.gramfort@telecom-paristech.fr&gt;\n#\n# License: BSD (3-clause)\n\n#https://gist.github.com/agramfort/850437\n\n#from scipy import linalg \nfrom numpy import linalg\n\ndef gramfort_lowess(x, y, f=2. / 3., iter=3):\n\n #&quot;&quot;&quot;lowess(x, y, f=2./3., iter=3) -&gt; yest\n #Lowess smoother: Robust locally weighted regression.\n #The lowess function fits a nonparametric regression curve to a scatterplot.\n #The arrays x and y contain an equal number of elements; each pair\n #(x[i], y[i]) defines a data point in the scatterplot. The function returns\n #the estimated (smooth) values of y.\n #The smoothing span is given by f. A larger value for f will result in a\n #smoother curve. The number of robustifying iterations is given by iter. The\n #function will run faster with a smaller number of iterations.\n #&quot;&quot;&quot;\n\n n = len(x)\n #r = int(ceil(f * n)) #update fe\n r = int(np.ceil(f * n)) #update fe \n h = [np.sort(np.abs(x - x[i]))[r] for i in range(n)]\n w = np.clip(np.abs((x[:, None] - x[None, :]) / h), 0.0, 1.0)\n w = (1 - w ** 3) ** 3\n yest = np.zeros(n)\n delta = np.ones(n)\n for iteration in range(iter):\n for i in range(n):\n weights = delta * w[:, i]\n b = np.array([np.sum(weights * y), np.sum(weights * y * x)])\n A = np.array([[np.sum(weights), np.sum(weights * x)],\n [np.sum(weights * x), np.sum(weights * x * x)]])\n beta = linalg.solve(A, b)\n yest[i] = beta[0] + beta[1] * x[i]\n\n residuals = y - yest\n s = np.median(np.abs(residuals))\n delta = np.clip(residuals / (6.0 * s), -1, 1)\n delta = (1 - delta ** 2) ** 2\n\n return yest\n\n\n#......................................................\n\ntemp_file = tempfile.NamedTemporaryFile(mode=&quot;w+t&quot;, prefix=&quot;GC_&quot;, suffix=&quot;.html&quot;, delete=False)\n\n#......................................................\nxtext=&quot;Pace/100m (min:sec)&quot;\nytext=&quot;Stroke Rate/min (srm)&quot;\n\npushoff=3 ## push-off compensation (m)\nstrokestyle=1 ## 1=freestyle, 2=backstroke, 3=breaststroke, 4=butterfly\n\n## plot colors\nregionlowfill=&apos;rgb(80,118,163)&apos;\n# regionlowborder&lt;-&quot;#5076a3&quot;\nregionhighfill=&apos;rgb(163,75,73)&apos;\n# regionhighborder&lt;-&quot;#a34b49&quot;\nplot_bgc=&apos;rgb(25,25,25)&apos;\npaper_bgc=&apos;rgb(20,20,20)&apos;\n\nsb_size_min=1\nsb_size_max=70\nsb_alpha=0.5\n\n## plot symbols\npl25=&apos;circle&apos;#21\npl50=&apos;square&apos;#22\nplx=&apos;diamond&apos;#23\n\n#plot limits\nxmin=130\nxmax=60\nymin=30\nymax=100\n\nstroketext=[&quot;Freestyle&quot;, &quot;Backstroke&quot;, &quot;Breaststroke&quot;, &quot;Butterfly&quot;]\nheader=(str(stroketext[strokestyle-1])+&quot; stroke rate chart&quot;)\n\n## ticks\nat=np.arange(xmin,xmax-10,-10)\nat_ms=[&apos;%d:%02d&apos;%(x/60,x%60) for x in at]\n\n## region low\nx_region1=at #[130 ,120 ,110 ,100 ,90 ,80 ,70 ,60]\nregion_low=[50.0,50.8,51.6,53.0,54.5,57.0,61.0,67.0] \n\n## region high\nx_region2=[130 ,120 ,110 ,100 ,95.5,90 ,80 ,70 ,67]\nregion_high=[61.8,63.4,65.2,68.0,70.0,73.1,83.1,96.0,100.0]\n\n#......................................................\n\n## data \n\nswim_field=[&apos;SWIM_TYPE&apos;,&apos;SWIM_DURATION&apos;,&apos;SWIM_STROKES&apos;]\n\nmetrics=GC.activityMetrics(compare=True)\n\nact_datetime=[[metrics[i][0][y] for y in[&apos;date&apos;,&apos;time&apos;]] for i in range(0,len(metrics))]\n\nact_list=[GC.activity(activity=datetime.datetime.combine(act_datetime[i][0],act_datetime[i][1])) for i in range(0,len(act_datetime))]\n\n#......................................................\n\ntrace=[]\nlayout=dict(paper_bgcolor=paper_bgc,plot_bgcolor=plot_bgc)\n\n##\nfor i in range(0,len(act_list)):\n\n if &quot;SWIM_TYPE&quot; in act_list[i]:\n\n swim=[];pace=[];sr=[];pace_sr=[];pl=[];f=[];pl_x_unique=[]\n pl_y_unique=[];trace_sm_lowess=[];trace_pace_sr=[] \n\n swim=np.array_split([np.array(list(act_list[i][y]))[np.array(list(act_list[i][&apos;SWIM_TYPE&apos;]))==strokestyle] for y in swim_field],1)\n\n if &quot;Pool_Length&quot; in metrics[i][0]: \n Pool_Length=int(metrics[i][0][&apos;Pool_Length&apos;])\n else:\n Pool_Length=0\n\n pointfill=metrics[i][1]\n\n if Pool_Length==25: sb1=pl25 #25 #circle\n elif Pool_Length==50: sb1=pl50 #50 #square \n else: sb1=plx #custom #diamond\n\n pace=swim[0][1]*100/Pool_Length\n\n sr=(60*2*swim[0][2]/swim[0][1])/(1-pushoff/Pool_Length) \n\n pace_sr=np.array([pace,sr])\n\n\n #........................................................\n\n # License: BSD (3-clause)\n pl=gramfort_lowess(pace, sr, f=2./3.) # return y\n # ......................\n \n pl_x_unique=np.unique(np.round(pace),return_index=True,return_counts=True) \n pl_y_unique=np.round(pl[pl_x_unique[1]],2) \n f=pl_x_unique[2]/max(pl_x_unique[2]) \n\n #........................................................\n\n trace_sm_lowess=dict(\n x=pl_x_unique[0],y=pl_y_unique,\n mode=&apos;lines+markers&apos;, \n name=metrics[i][0][&apos;date&apos;].strftime(&apos;%A %y-%m-%d&apos;),#&apos;sm_lowess &apos;+str(i+1),\n marker=dict(size=(sb_size_min+(sb_size_max-sb_size_min)*f),opacity=0.4,size_max=70,symbol=sb1),\n line = dict(color=pointfill,width=1,opacity=1))\n trace.append(trace_sm_lowess)\n\n#......................................................\n\n##\nif &apos;SWIM_TYPE&apos; in act_list[0]: \n\n trace_region_low=dict(x=x_region1,y=region_low,\n mode=&apos;lines&apos;,hoverinfo=&apos;skip&apos;,showlegend=False,\n fill=&apos;tozeroy&apos;,\n line = dict(color=regionlowfill,width=0.1,opacity=0.6))\n trace.append(trace_region_low)\n\n trace_region=dict(x=x_region2,y=region_high,\n mode=&apos;lines&apos;,hoverinfo=&apos;skip&apos;,showlegend=False,\n line = dict(color=regionhighfill,width=0.1,opacity=0.6))\n trace.append(trace_region)\n\n trace_region_high=dict(x=x_region2,y=[100*len(region_high)],\n mode=&apos;lines&apos;,hoverinfo=&apos;skip&apos;,showlegend=False, \n fill=&apos;tonexty&apos;,\n line = dict(color=regionhighfill,width=0.1,opacity=0.6))\n trace.append(trace_region_high)\n\n minor_xaxis=dict(overinfo=&apos;skip&apos;,showlegend=False,xaxis=&apos;x2&apos;)\n trace.append(minor_xaxis)\n minor_yaxis=dict(overinfo=&apos;skip&apos;,showlegend=False,yaxis=&apos;y2&apos;)\n trace.append(minor_yaxis)\n\n##\n text=[]\n text.append(dict(x=min(at)+(max(at)-min(at))/2,y=32,text=&apos;Low Stroke rate&apos;,font=dict(size=12,color=&apos;rgb(0,0,255)&apos;),showarrow=False))\n text.append(dict(x=min(at)+(max(at)-min(at))/2,y=96.5,text=&apos;High Stroke rate&apos;,font=dict(size=12,color=&apos;rgb(255,0,0)&apos;),showarrow=False))\n text.append(dict(x=min(at)+(max(at)-min(at))/2,y=99,text=u&apos;\u25ef&apos;+&apos; 25 &apos;+u&apos;\u20de&apos;+&apos; 50 &apos;+u&apos;\u20df&apos;+&apos; custom&apos;,font=dict(size=11,color=&apos;white&apos;),showarrow=False))\n\n##\n layout=dict(\n paper_bgcolor=paper_bgc,\n plot_bgcolor=plot_bgc,\n title=header,\n titlefont=dict(color=&apos;white&apos;,size=18),\n hovermode=&apos;x&apos;,\n margin=dict(pad=20), \n xaxis=\n(dict(range=[xmin,xmax],titlefont=dict(size=13,color=&apos;rgb(132,159,190)&apos;),linewidth=1,ticks=&quot;outside&quot;,color=&apos;white&apos;, tickwidth=0.5,ticklen=8,title=xtext,tickfont=dict(size=12,color=&apos;rgb(132,159,190)&apos;),tickvals=at,ticktext=at_ms,mirror=True)),\n yaxis = dict(range=[ymin,ymax],titlefont=dict(size=13,color=&apos;rgb(132,159,190) &apos;),linewidth=1,ticks=&quot;outside&quot;,color=&apos;white&apos;,tickwidth=0.5,ticklen=8,title=ytext,tickfont=dict(size=12,color=&apos;rgb(132,159,190)&apos;),mirror=True),\n xaxis2 = dict(range=[xmax,xmin],showgrid=False,ticks=&quot;outside&quot;,color=&apos;white&apos;,ticklen=4,tick0 = xmax, showticklabels=False,overlaying = &apos;x&apos;, dtick = 1),\n yaxis2 = dict(range=[ymax,ymin],showgrid=False,ticks=&quot;outside&quot;,color=&apos;white&apos;,ticklen=4,tick0 = xmax, showticklabels=False,overlaying = &apos;y&apos;, dtick = 1),\n annotations=text,legend=dict(font=dict(size=11,color=&apos;lightgreen&apos;),orientation=&quot;h&quot;,y=-0.24,xanchor=&quot;left&quot;,x=-0.03,yanchor=&quot;bottom&quot;))\n\n\n#......................................................\n\n##\nfig=dict(data=trace,layout=layout)\n\n\nply.offline.plot(fig,auto_open = False, filename=temp_file.name, validate=False)\n\nGC.webpage(pathlib.Path(temp_file.name).as_uri())\n" />
<property name="state" type="QString" value="" />
<property name="plotOnChart" type="bool" value="0" />
<property name="showConsole" type="bool" value="0" />
<property name="asWeb" type="bool" value="1" />
</chart>
<chart id="37" name="" title="Map" >
<property name="title" type="QString" value="Map" />
Expand Down

0 comments on commit cc6738b

Please sign in to comment.