Plot Tools

To help you create some more common shapes using plots, we have created a fragment called plotTools.xml, available below. The plot tools fragment contain functions that can be called when included in your document to draw shapes, numbers, and common charts. Just pass the name of the plot series and the required parameters to the function and it will add the appropriate data to the plot.

To add the plot tools fragment to your app, download it by clicking the button above. Unzip the folder. You can drag-and-drop the xml file directly into your project in the solution explorer window in Visual Studio, or you can right click on your module and click Add > Existing Item (you may have to switch the file type from Visual C# Files to All Files).

Once added to your project, include the fragment in your module by placing the following code at the top of your document (above your first section).

<include src="plotTools.xml" />

Capacity

Shapes that are large in size may skew or not be drawn completely. This is due to the default capacity of a series, which determines how many points can be drawn in a single series. The default capacity is 5000 points. If you are creating large shapes, increase the capacity of the points in the series to ensure that the entire shape is drawn.

The below example demonstrates the effect of capacity on a shape. Two circles of equal radius are drawn, but the first series does not have a large enough capacity to draw the entire circle. 

<script>
  plotTools.drawCircle(myCirclePlot.first_series, vector({-15,0}), 10)
  plotTools.drawCircle(myCirclePlot.second_series, vector({15,0}), 10)
</script>

<xyPlot name="myCirclePlot">
  <axis dim="x" auto="growAndShrink" />
  <axis dim="y" auto="lockAspectRatio" />
  <series name="first_series" manual="true" />
  <series name="second_series" manual="true" capacity="8000" />
</xyPlot>
 
changing-series-capacity.jpg
 

Shapes

The following code includes the plot tools, and then draws shapes on a plot. If you would like to create a filled shape, set the draw mode to radialFill. 

<include src="plotTools.xml" />

<sectionNoTitle>
  <script>
    <![CDATA[
   -- plotTools.drawSquare([Series],[Centre],[Width],[Height])
   plotTools.drawSquare(plot.square_series, vector({0,0}), 10, 10)
 
   -- plotTools.drawArrow([Series],[Start],[End])
   plotTools.drawArrow(plot.arrow_series, vector({-5,-5}), vector({10,10}))
 
   -- plotTools.drawCircle[Series],[Centre],[Radius])
   plotTools.drawCircle(plot.circle_series, vector({-10,-10}), 5)
   
   -- plotTools.drawEllipse([Series],[Centre],[X-radius],[Y-radius])
   plotTools.drawEllipse(plot.ellipse_series, vector({-15, 5}), 1.5, 4)
  
   -- plotTools.drawArc([Series],[Start Angle],[End Angle],[Centre],[Radius])
   plotTools.drawArc(plot.arc_series, 10, -210, vector({5,5}), 3)
   
   -- plotTools.drawEllipseArc([Series],[Start Angle],[End Angle],[Centre],[X-radius],[Y-radius])
   plotTools.drawEllipseArc(plot.ellipseArc_series, 10, 210, vector({0,12}), 5, 2)
   
   
   -- Filled Shapes
   
   -- plotTools.drawSquare([Series],[Centre],[Width],[Height])
   plotTools.drawSquare(plot.filled_square_series, vector({-10,8}), 4, 6)
   
   -- plotTools.drawCircle[Series],[Centre],[Radius])
   plotTools.drawCircle(plot.filled_circle_series, vector({10,-10}), 4)
   
   -- plotTools.drawEllipse([Series],[Centre],[X-radius],[Y-radius])
   plotTools.drawEllipse(plot.filled_ellipse_series, vector({15, 5}), 3, 2)
]]>
  </script>
  <xyPlot name="plot">
    <axis dim="x" auto="lockAspectRatio" />
    <axis dim="y" auto="growAndShrink" />
    <series name="square_series" manual="true" />
    <series name="arrow_series" manual="true" />
    <series name="circle_series" manual="true" />
    <series name="ellipse_series" manual="true" />
    <series name="arc_series" manual="true" />      
    <series name="ellipseArc_series" manual="true" />
    <series name="filled_square_series" manual="true" draw="radialFill" />
    <series name="filled_circle_series" manual="true" draw="radialFill" />
    <series name="filled_ellipse_series" manual="true" draw="radialFill" />
  </xyPlot>
</sectionNoTitle>
 
plot-tools-shapes.jpg
 

Shapes can be also be colored by specifying a color in the function call, or by applying a style with a foreground color to the plot series. To specify a color in the function call, use the color's X11 color name (color.seaGreen) or its rgb value (color.rgb(255, 0, 0)).

<include src="plotTools.xml"/>

<script>
  <![CDATA[
   -- plotTools.drawSquare([Series],[Centre],[Width],[Height],[CustomColor])
   plotTools.drawSquare(plot.square_series, vector({0,0}), 10, 10, color.black)
 
   -- plotTools.drawArrow([Series],[Start],[End],[CustomColor])
   plotTools.drawArrow(plot.arrow_series, vector({-5,-5}), vector({10,10}), color.black)
 
   -- plotTools.drawCircle[Series],[Centre],[Radius],[CustomColor])
   plotTools.drawCircle(plot.circle_series, vector({-10,-10}), 5, color.black)
   
   -- plotTools.drawEllipse([Series],[Centre],[X-radius],[Y-radius],[CustomColor])
   plotTools.drawEllipse(plot.ellipse_series, vector({-15, 5}), 1.5, 4, color.black)
  
   -- plotTools.drawArc([Series],[Start Angle],[End Angle],[Centre],[Radius],[CustomColor])
   plotTools.drawArc(plot.arc_series, 10, -210, vector({5,5}), 3, color.black)
   
   -- plotTools.drawEllipseArc([Series],[Start Angle],[End Angle],[Centre],[X-radius],[Y-radius],[CustomColor])
   plotTools.drawEllipseArc(plot.ellipseArc_series, 10, 210, vector({0,12}), 5, 2, color.black)
   
   
   -- Filled Shapes
   
   -- plotTools.drawSquare([Series],[Centre],[Width],[Height],[CustomColor])
   plotTools.drawSquare(plot.filled_square_series, vector({-10,8}), 4, 6, color.black)
   
   -- plotTools.drawCircle[Series],[Centre],[Radius],[CustomColor])
   plotTools.drawCircle(plot.filled_circle_series, vector({10,-10}), 4, color.black)
   
   -- plotTools.drawEllipse([Series],[Centre],[X-radius],[Y-radius],[CustomColor])
   plotTools.drawEllipse(plot.filled_ellipse_series, vector({15, 5}), 3, 2, color.black)
  ]]>
</script>
 
plot-tools-shapes-black.jpg
 

Numbers and Symbols

The plotTools fragment also includes functions for drawing the numbers 0 through 9, and common mathematical symbols. When using these functions, specify the series, anchor, height, and color as parameters for each number added. The anchor specifies the position of the number, using the x- and y-coordinates of the bottom-left corner of the number.

Numbers and symbols will default to a height of 1 and a color of black unless otherwise specified. Note that multiple numbers can be added to a single plot series. 

The following code includes the plotTools fragment, and draws the numbers 0 through 9.

<include src="plotTools.xml" />
    
<sectionNoTitle> 
    <script>
      <![CDATA[
      --char.num1([Series], [Anchor], [Height], [CustomColor])
      char.num1(myDrawing.numberSeries, vector({0, 0}), 2, color.red)
      char.num2(myDrawing.numberSeries, vector({2, 0}), 2, color.red)
      char.num3(myDrawing.numberSeries, vector({4, 0}), 2, color.red)
      char.num4(myDrawing.numberSeries, vector({6, 0}), 2, color.red)
      char.num5(myDrawing.numberSeries, vector({8, 0}), 2, color.red)
      char.num6(myDrawing.numberSeries, vector({10, 0}), 2, color.red)
      char.num7(myDrawing.numberSeries, vector({12, 0}), 2, color.red)
      char.num8(myDrawing.numberSeries, vector({14, 0}), 2, color.red)
      char.num9(myDrawing.numberSeries, vector({16, 0}), 2, color.red)
      char.num0(myDrawing.numberSeries, vector({18, 0}), 2, color.red)
      
      -- Height will default to 1 and color will default to black 
      char.num1(myDrawing.numberSeries, vector({0, -2}))
      char.num2(myDrawing.numberSeries, vector({2, -2}))
      char.num3(myDrawing.numberSeries, vector({4, -2}))
      char.num4(myDrawing.numberSeries, vector({6, -2}))
      char.num5(myDrawing.numberSeries, vector({8, -2}))
      char.num6(myDrawing.numberSeries, vector({10, -2}))
      char.num7(myDrawing.numberSeries, vector({12, -2}))
      char.num8(myDrawing.numberSeries, vector({14, -2}))
      char.num9(myDrawing.numberSeries, vector({16, -2}))
      char.num0(myDrawing.numberSeries, vector({18, -2}))
      ]]>
    </script>
    
    <xyPlot name="myDrawing">
      <axis dim="x" auto="growAndShrink" />
      <axis dim="y" auto="lockAspectRatio" />
      <series name="numberSeries"/>
    </xyPlot>
    
</sectionNoTitle>
 
plot-tools-numbers.jpg
 

The following code includes the plotTools fragment, and draws the included symbols.

<include src="plotTools.xml" />

<sectionNoTitle>
  <script>
    local symbolSeries = symbolPlot.symbolSeries
    
    --symbol.drawPlus([Series], [Anchor], [Height], [Color])
    symbol.drawPlus(symbolSeries, {0,0})
    symbol.drawMinus(symbolSeries, {1,0})
    symbol.drawMult(symbolSeries, {2,0})
    symbol.drawDiv(symbolSeries, {3,0})
    symbol.drawEqual(symbolSeries, {4,0})
    symbol.parenthesisLeft(symbolSeries, {5,0})
    symbol.parenthesisRight(symbolSeries, {6,0})
  </script>

  <xyPlot name="symbolPlot">
    <axis dim="x" auto="growAndShrink" />
    <axis dim="y" auto="lockAspectRatio" />
    <series name="symbolSeries" />
  </xyPlot>

</sectionNoTitle>
 
plot-tools-symbols.jpg
 

Letters

Using the plotTools fragment, you can create in-plot labels and identifiers using the letter functions. When using these functions, specify the series, anchor, height, and color as parameters for each letter added. The anchor specifies the position of the letter, using the x- and y-coordinates of the bottom-left corner of the letter. Note that multiple letters can be added to a single plot series. Similar to the number functions, the letter functions will default to a height of 1 and a color of black unless specified. 

The following code includes the plotTools fragment, and draws the letters A through Z.

<include src="plotTools.xml" />

<sectionNoTitle>
  <script>
    local alphabet = alphabetPlot.series;
    
    --char.textA([Series], [Anchor], [Height], [CustomColor])
    char.textA(alphabet, {0,0}, 1)
    char.textB(alphabet, {0,-2}, 1)
    char.textC(alphabet, {0,-4}, 1)
    char.textD(alphabet, {0,-6}, 1)
    char.textE(alphabet, {0,-8}, 1)
    char.textF(alphabet, {0,-10}, 1)
    char.textG(alphabet, {0,-12}, 1)
    char.textH(alphabet, {0,-14}, 1)
    char.textI(alphabet, {0,-16}, 1)
    char.textJ(alphabet, {0,-18}, 1)
    char.textK(alphabet, {0,-20}, 1)
    char.textL(alphabet, {0,-22}, 1)
    char.textM(alphabet, {0,-24}, 1)
    char.textN(alphabet, {2,0}, 1)
    char.textO(alphabet, {2,-2}, 1)
    char.textP(alphabet, {2,-4}, 1)
    char.textQ(alphabet, {2,-6}, 1)
    char.textR(alphabet, {2,-8}, 1)
    char.textS(alphabet, {2,-10}, 1)
    char.textT(alphabet, {2,-12}, 1)
    char.textU(alphabet, {2,-14}, 1)
    char.textV(alphabet, {2,-16}, 1)
    char.textW(alphabet, {2,-18}, 1)
    char.textX(alphabet, {2,-20}, 1)
    char.textY(alphabet, {2,-22}, 1)
    char.textZ(alphabet, {2,-24}, 1)
  </script>

  <xyPlot name="alphabetPlot">
    <axis dim="x" auto="lockAspectRatio" />
    <series name="series" />
  </xyPlot>

</sectionNoTitle>
 
plot-tools-letters.png
 

Charts

The plotTools fragment also includes functions that make it easier to create common charts. 

Pie Chart

To create a pie chart, create an xyPlot with the same parameters as those outlined below, but set the number of series to the number of slices that will be represented in the pie chart (i.e. the size of the vector of data). 

Define a vector of percentages representing your data. Call the pie chart function and specify the name of the plot and data vector. The pie chart can represent a maximum of 20 values.

<include src="plotTools.xml" />

<xyPlot name="myPlot" tap="disabled" series="4" >
  <axis dim="x" auto="lockAspectRatio" major="false" />
  <axis dim="y" auto="fixed" min="-11" max="11" major="false" />
</xyPlot>

<script>
  pieData = vector({40, 30, 20, 10})
  
  --chart.pie([Plot], [Vector])
  chart.pie(myPlot, pieData)
</script>
 
plot-tools-chart.jpg
 

Bar Chart

You can create both vertical and horizontal bar charts using plotTools. Start by creating an xyPlot with the same parameters as those outlined below, and set the number of series to the number of bars. Call the appropriate function and specify the name of the plot, the bar width, and the name of the data matrix.

A recommended bar width is the smallest difference between independent variables. Decreasing the width creates more white space between bars.

<include src="plotTools.xml" />

<xyPlot name="myBarChart" series="10">
  <axis dim="x" auto="growAndShrink" />
  <axis dim="y" auto="growAndShrink" />
</xyPlot>

<script>
  barData = matrix({{1,25}, {2,10}, {3.5,15}, {4,22}, {5.25,18}, {6,33}, {7,40}, {8,-8}, {9,24}, {10,10}});
  
  --chart.bar([Plot], [Width], [Matrix])
  chart.bar(myBarChart, 0.5, barData);
</script>
 
plot-tools-bar-chart.jpg
 
<include src="plotTools.xml" />

<xyPlot name="aBarChart" series="10">
  <axis dim="x" auto="growAndShrink" />
  <axis dim="y" auto="growAndShrink" />
</xyPlot>

<script>
  barData = matrix({{1,25}, {2,10}, {3.5,15}, {4,22}, {5.25,18}, {6,33}, {7,40}, {8,-8}, {9,24}, {10,10}});
  
  --chart.barH([Plot], [Width], [Matrix])
  chart.barH(aBarChart, 0.5, barData);
</script>
 
plot-tools-bar-chart-horizontal.jpg
 

If any of your bar chart data overlaps, reduce the width of the bars.

Line Chart

To create a line chart, create an xyPlot with the same parameters as those outlined below, but set the number of series to twice the number of data sets that will be presented on the plot. Call the line chart function and specify the name of the plot, the data set, and the data matrix.

<include src="plotTools.xml" />

<xyPlot name="myLinePlot" series="8">
  <axis dim="x" auto="growAndShrink" />
  <axis dim="y" auto="growAndShrink" />
</xyPlot>

<script>  
 data1 = matrix({{1,24}, {10,36}, {15,2}, {22,9}, {50,5}, {55,-3}, {60,12}, {62,50}, {63,11}, {65,44}});
 data2 = matrix({{2,-24}, {15,36}, {17,-2}, {20,9}, {30,-5}, {35,-3}, {40,12}, {42,-50}, {43,11}, {45,44}});
 data3 = matrix({{2,-4}, {15,3}, {17,-20}, {20,90}, {30,-5.1}, {35,3}});
 data4 = matrix({{35,-3}, {40,12}, {42,-50}, {43,11}, {45,44}});

 --chart.line([Plot], [Set], [Matrix])
 chart.line(myLinePlot, 1, data1)
 chart.line(myLinePlot, 2, data2)
 chart.line(myLinePlot, 3, data3)
 chart.line(myLinePlot, 4, data4)
</script>
 
plot-tools-line-chart.jpg
 

Area Chart

To create an area chart, create an xyPlot with the same parameters as those outlined below, but set the number of series to the number of data sets that will be presented on the plot. Call the area chart function and specify the name of the plot, the data set, and the data matrix.

Negative y-values cannot be added to an area chart at this time.

<include src="plotTools.xml" />

<xyPlot name="myAreaPlot" series="3">
  <axis dim="x" auto="growAndShrink" />
  <axis dim="y" auto="growAndShrink" />
</xyPlot>

<script>
  data = matrix({{1,34}, {10,46}, {15,10}, {22,20}, {50,10}, {55,10}, {60,15}, {62,55}, {63,15}, {65,45}});
  data2 = matrix({{1,24}, {10,36}, {15,2}, {22,9}, {50,5}, {55,3}, {60,12}, {62,50}, {63,11}, {65,44}});
  data3 = matrix({{1,20}, {10,30}, {15,1}, {22,5}, {50,0}, {55,0}, {60,5}, {62,40}, {63,6}, {65,35}});

  -- chart.area([Plot], [Set], [Matrix])
  chart.area(myAreaPlot, 1, data)
  chart.area(myAreaPlot, 2, data2)
  chart.area(myAreaPlot, 3, data3)
</script>
 
plot-tools-area-chart.jpg
 

Scatter Plot with Line of Fit

To create a scatter plot, create an xyPlot with the same parameters as those outlined below, but set the number of series to twice the number of data sets that will be presented on the plot.. Call the scatter plot function and specify the name of the plot, the data set, and the data matrix.

<include src="plotTools.xml" />

<xyPlot name="myScatterPlot" series="2">
  <axis dim="x" auto="growAndShrink" />
  <axis dim="y" auto="growAndShrink" />
</xyPlot>

<script>
  pointsMatrix = matrix(250, 2, function (i,j) return i+j*math.random(-15,15); end);
  
  -- chart.scatter([Plot], [Set], [Matrix])
  chart.scatter(myScatterPlot, 1, pointsMatrix)
</script>
 
plot-tools-scatter-chart.jpg