Python Code to Generate SVG Pie Chart

November 16, 2010

Here's some code that will generate an SVG pie chart from Python.

Set lSlices equal to a tuple containing the percentages you want to display.

import math

lSlices = (25,25,45,5) # percentages to show in pie

lOffsetX = 150
lOffsetY = 150

lRadius = 100

def endpoint(pAngleInRadians, pRadius, pCentreOffsetX, pCentreOffsetY):
  """
  Calculate position of point on circle given an angle, a radius, and the location of the center of the circle
  Zero line points west.
  """
  lCosAngle = math.cos(pAngleInRadians)
  lSinAngle = math.sin(pAngleInRadians)
  lStartLineDestinationX =  pCentreOffsetX - (lRadius * lCosAngle)
  lStartLineDestinationY =  pCentreOffsetY - (lRadius * lSinAngle)

  return (lStartLineDestinationX, lStartLineDestinationY)

GRADIENTS = ('myRadialGradientGreen', 'myRadialGradientOrange', 'myRadialGradientGreen', 'myRadialGradientOrange', )
DEGREES_IN_CIRCLE = 360.0
lSvgPath = ""
lCurrentAngle = 0
lTotalSlices = 0
lIndex = 0
lSvgPath = ""
for x in lSlices:
  lTotalSlices += x

print lTotalSlices

for lSlice in lSlices:
  lLineOneX, lLineOneY = endpoint(lCurrentAngle, lRadius, lOffsetX, lOffsetY)
  lLineOne = "M%d,%d L%d,%d" % (lOffsetX, lOffsetY, lLineOneX, lLineOneY)

  lPercent = lSlice
  print "percent = %d " % lPercent
  lDegrees = (DEGREES_IN_CIRCLE / lTotalSlices) * lSlice
  print "degrees = %d " % lDegrees
  lRadians = math.radians(lDegrees)
  lCurrentAngle += lRadians
  print "current angle = %f %f" % (lCurrentAngle, math.degrees(lCurrentAngle))
  lLineTwoX, lLineTwoY = endpoint(lCurrentAngle, lRadius, lOffsetX, lOffsetY)

  lRoute = 0
  if lDegrees > 180:
    lRoute = 1
  lArc = "A%d,%d 0 %d,1 %d %d" % (lRadius, lRadius, lRoute, lLineTwoX, lLineTwoY)
  lLineTwo = "L%d,%d" % (lOffsetX, lOffsetY)

  lPath = "%s %s %s" % (lLineOne, lArc, lLineTwo)
  lGradient = GRADIENTS[lIndex]
  lSvgPath += "<path d='%s' style='stroke:#660000; fill:url(#%s);'/>" % (lPath, lGradient)
  lIndex += 1

lSvg = """
<svg  xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <radialGradient id="myRadialGradientGreen" r="65%%" cx="0" cy="0" spreadMethod="pad">
      <stop offset="0%%"   stop-color="#00ee00" stop-opacity="1"/>
      <stop offset="100%%" stop-color="#006600" stop-opacity="1" />
    </radialGradient>
  </defs>
  <defs>
    <radialGradient id="myRadialGradientOrange" r="65%%" cx="0" cy="0" spreadMethod="pad">
      <stop offset="0%%"   stop-color="#ffee00" stop-opacity="1"/>
      <stop offset="100%%" stop-color="#ff6600" stop-opacity="1" />
    </radialGradient>
  </defs>

  %s
<!--  <circle cx="%d" cy="%d" r="100" style="stroke:#006600; fill:none;"/> -->
</svg>
""" % (lSvgPath, lOffsetX, lOffsetY)

print lSvg

lFile = open('test.svg', 'w')
lFile.write(lSvg)
lFile.close()

References

Tags: svg python pie