示例#1
0
def create_svg(liste_points):
	window = svgfig.window(years_bins[0][0], years_bins[-1][-1], 0, 1000,width=100,height=100)
	#def window(xmin, xmax, ymin, ymax, x=0, y=0, width=100, height=100, xlogbase=None, ylogbase=None, minusInfinity=-1000, flipx=False, flipy=True):
	graph = svgfig.SVG("g", id="Tubes")
	labels = svgfig.SVG("g", id="Labels")
	for points in liste_points:
		poly = svgfig.Poly(points, "smooth", stroke="#eeeeee",  stroke_width="0.2",fill='#cccccc')##fill=self.rgb2hex(self.colors[layer])
		graph.append(poly.SVG(window))
		graph.append(poly.SVG(window))	
	graph.save("svg/tmp.svg")
示例#2
0
def swiss_draw_karyotype():
    from svgfig import Rect, Fig, window
    chr = ''
    chr_y = 0
    clen = 0
    rects = []
    shades = {
        'gneg': '#ffffff',  #(0,0%,100%)',
        'gpos25': '#c0c0c0',
        'gpos50': '#808080',
        'gpos75': '#404040',
        'gpos100': '#000000',
        'acen': '#ff0000',
        'gvar': '#ffffff',
        'stalk': '#ffffff',
    }

    def draw_border():
        rects.append(
            Rect(-w, chr_y, w, chr_y + clen, fill=None, stroke_width='0.05pt'))

    for line in open('/data/csb/organisms/homo_sapiens/cytoband.txt'):
        c = line.rstrip().split('\t')
        pos = (float(c[1]) / 1000000, float(c[2]) / 1000000)
        if c[0] != chr:
            if chr: draw_border()
            chr = c[0]
            chr_y += clen + 20
            clen = 0
        clen = max(clen, pos[1])
        w = 0.01 if c[4] == 'acen' else 0.02
        rects.append(
            Rect(-w,
                 chr_y + pos[0],
                 w,
                 chr_y + pos[1],
                 stroke='none',
                 fill=shades[c[4]],
                 stroke_linejoin='miter'))

    draw_border()

    Fig(*rects, trans=window(0, 20, 0, chr_y + clen, width=500)).SVG() \
     .save('/home/annalam/karyotype.svg')
示例#3
0
def mpoplot(userdates, master_scale=15, demo=False):
    """
    ... explain what this does...
    """

    outdir = '../sample_data/output'
    # if demo:
    #     shutil.rmtree(outdir)
    #     os.makedirs(outdir)
    # else:
    #     if not os.path.exists(outdir):
    #         os.makedirs(outdir)
    #     else:
    #         print('\n   Uh-oh! The directory {} already exists.'.format(
    #             outdir))
    #         if yesno('   Do you want to replace it?'):
    #             shutil.rmtree(outdir)
    #             os.makedirs(outdir)
    #         else:
    #             return

    # Clear and load the kernels that this program requires.
    spice.kclear()
    spice.furnsh('epys.mk')

    # A graphic will be created for each 'date' in 'dates':
    for date in userdates:

        et = spice.str2et(date)
        datestr = (spice.et2utc(et, 'ISOC', 0))

        # -- Outer frame -------------------------------------------------

        dist_scl = 250.0

        elts = getorbelts(date)
        arg_peri = elts[4]

        # Opacity of degree frame and Venus graphic
        frame_op = 0.5

        # # Process JD time into calendar time strings
        # datestr = spice.et2utc(et, 'ISOC', 0)
        date = '{} {}'.format(datestr.split('T')[0],
                              datestr.split('T')[1])
        edate, etime = date.split()
        eyear = "{}".format(edate.split('-')[0])
        emonth = "{0:02d}".format(int(edate.split('-')[1]))
        eday = "{0:02d}".format(int(edate.split('-')[2]))
        epoch = "{}/{}/{}".format(eday, emonth, eyear)
        ep_name = "{}{}{}".format(eyear, emonth, eday)

        frame = _outerframe(epoch, frmSize=master_scale, frm_op=frame_op,
                            mpoargp=arg_peri)

        # -- Mercury Planet --------------------------------------------------

        # tru_ano = 90
        # look_from = 270

        # x1 = "{}%".format((100*math.sin(math.radians((tru_ano+90)/2.))))
        # x2 = "{}%".format(100-(100*sin(radians((tru_ano+90)/2.))))

        angs = range(0, 360, 1)

        plt.plot(angs, ["{}".format((100 * math.sin(math.radians(x / 2))))
                        for x in angs], 'yo-')
        plt.plot(angs, ["{}".format(100 - (100 *
                        math.sin(math.radians(x / 2)))) for x in angs], 'ro-')
        # plt.show()

        stop1 = "#C8C5E2"
        # stop2 = "#373163"

        defs = svg.SVG("defs",
                       svg.SVG("linearGradient",
                               svg.SVG("stop", stop_color=stop1,
                                       stop_opacity=1, offset="45%"),
                               svg.SVG("stop", stop_color=stop1,
                                       stop_opacity=1, offset="55%"),
                               x1="0%", y1="0%", x2="100%", y2="0%",
                               spreadMethod="pad",
                               id="mercGrad")
                       )

        # defs = svg.SVG('defs',
        #                svg.SVG('radialGradient',
        #                        svg.SVG('stop',
        #                                stop_color=stop1,
        #                                stop_opacity=1,
        #                                offset='38%'),
        #                        svg.SVG('stop',
        #                                stop_color=stop2,
        #                                stop_opacity=1,
        #                                offset='40%'),
        #                        cx='50%', cy='50%',
        #                        fx='230%', fy='50%',
        #                        r='300%',
        #                        spreadMethod='pad',
        #                        id='mercGrad')
        #                )

        merc_rad = 2439.99  # km
        merc_rad_scl = merc_rad / dist_scl
        merc_ball = svg.Ellipse(0, 0, 0, merc_rad_scl, merc_rad_scl,
                                fill="url(#mercGrad)", stroke_width="0.15pt")

        # -- MPO Orbit --

        mpo_orb_ecc = 0.163229
        mpo_orb_sma = 3394.0  # km
        mpo_orb_sma_scl = mpo_orb_sma / dist_scl
        mpo_orb_smi_scl = mpo_orb_sma_scl * math.sqrt(1 - mpo_orb_ecc ** 2)

        # Make things cleaner
        a = mpo_orb_sma_scl
        b = mpo_orb_smi_scl

        mpo_orb = svg.Ellipse(-math.sqrt(a ** 2 - b ** 2), 0, 0, a, b,
                              fill="none", stroke_width="0.25pt")
        # apof = 8
        mpo_orb_apses = svg.Line(-_rellipse(a, b, 180) - 5, 0,
                                 _rellipse(a, b, 0) + 10, 0,
                                 stroke_width="0.15pt",
                                 stroke_dasharray="2, 2")

        dot_angs = range(0, 360, 20)
        dots = [_orbitdot(a, b, x, color="black") for x in dot_angs]
        mpo_orb_dots = svg.Fig()
        for dot in dots:
            mpo_orb_dots.d.append(dot)

        mpo_orb_trans = svg.rotate(arg_peri, 0, 0)
        mpo_orb_plot = svg.Fig(mpo_orb, mpo_orb_apses, mpo_orb_dots,
                               trans=mpo_orb_trans)

        # -- Direction arrow -------------------------------------------------

        dirarend = svg.make_marker("dirarrowend", "arrow_end",
                                   fill_opacity=0.2)
        dirarend.attr["markerWidth"] = 7.5

        x1, y1 = master_scale + 1, 0.4,
        x2, y2 = master_scale + 1, 1

        dirarwstrt = svg.Line(x1, y1, x2, y2, stroke_width=".4pt",
                              stroke_opacity=0.2, arrow_end=dirarend)

        dirarw = svg.Fig(dirarwstrt, trans="x*cos(y), x*sin(y)")

        # -- Apsis view ------------------------------------------------------

        apvx, apvy = master_scale + 3, -master_scale - 3
        apsisviewball = svg.Ellipse(apvx, apvy,
                                    0, merc_rad_scl * 0.25,
                                    merc_rad_scl * 0.25,
                                    fill="url(#mercGrad)",
                                    stroke_width="0.15pt")

        apsisviewlats = svg.Fig()

        for x in range(-9, 10, 3):

            hscl = math.sin(math.radians(x * 10))
            wscl = math.cos(math.radians(x * 10))

            x1 = apvx - (merc_rad_scl * 0.25 * wscl)
            y1 = apvy + (merc_rad_scl * 0.25 * hscl)
            x2 = apvx + (merc_rad_scl * 0.25 * wscl)
            y2 = apvy + (merc_rad_scl * 0.25 * hscl)

            apsisviewlats.d.append(svg.Line(x1, y1, x2, y2,
                                   stroke_width=".2pt",
                                   stroke_opacity=0.4))

        apvarend = svg.make_marker("apvarrowend",
                                   "arrow_end",
                                   fill_opacity=0.6)
        apvarend.attr["markerWidth"] = 3.0
        apvarend.attr["markerHeight"] = 3.0

        x1, y1 = apvx, apvy - 3
        x2, y2 = apvx, apvy + 3
        apsisvieworbit = svg.Line(x1, y1, x2, y2,
                                  stroke_width=".4pt",
                                  stroke_opacity=0.6,
                                  arrow_end=apvarend)

        xd = apvx
        yd = apvy + (merc_rad_scl * 0.25 * math.sin(math.radians(arg_peri)))
        apsisviewdot = svg.Fig(svg.Dots([(xd, yd)],
                                        svg.make_symbol("apsisdot",
                                                        fill="black",
                                                        fill_opacity=0.6
                                                        ),
                                        0.6, 0.6
                                        )
                               )

        apsisview = svg.Fig(apsisviewball,
                            apsisviewlats,
                            apsisvieworbit,
                            apsisviewdot)

        # -- Build final figure ----------------------------------------------

        wa = master_scale * 1.5
        svgout = svg.Fig(frame,
                         merc_ball,
                         mpo_orb_plot,
                         dirarw,
                         apsisview
                         ).SVG(svg.window(-wa, wa, -wa, wa))

        svgout.prepend(defs)

        argp = int(arg_peri)
        svgout.save(os.path.join(outdir,
                                 "mpo_orbit_plot_{}_{}.svg".format(ep_name,
                                                                   argp)
                                 )
                    )
示例#4
0
def planetsplot(userdates=None, delta="1d", master_scale=15, demo=False,
                showplots=False):
    """
    ... explain what this does...
    """

    outdir = './sample_data/output'
    # if demo:
    #     shutil.rmtree(outdir)
    #     os.makedirs(outdir)
    # else:
    #     if not os.path.exists(outdir):
    #         os.makedirs(outdir)
    #     else:
    #         print('\n   Uh-oh! The directory {} already exists.'.format(
    #             outdir))
    #         if yesno('   Do you want to replace it?'):
    #             shutil.rmtree(outdir)
    #             os.makedirs(outdir)
    #         else:
    #             return

    orbitdata = _gatherorbitdata(delta=delta, scale=master_scale)
    ets, dates, orbits, argps, argpxys, nus = orbitdata

    if userdates is None:
        userdates = dates

    if showplots:
        plt.subplot(1, 1, 1)
        for xy in orbits:
            plt.plot([x[0] for x in xy], [y[1] for y in xy],
                     'rx', label='SPICE')
        for xy in argpxys:
            plt.plot(xy[0], xy[1], 'go')
        plt.show()

    if len(orbits[0]) == len(dates) == len(ets):

        # This rotation will put the Hermean perihelion on the X-axis.
        rotang = -argps[0]

        # Load the kernels that this program requires.
        spice.kclear()
        this_dir = os.path.dirname(os.path.realpath(__file__))
        spice.furnsh(os.path.join(this_dir, 'epys.mk'))

        output_files = []

        # A graphic will be created for each 'date' in 'userdates':
        for date in userdates:

            # get the position-index of the 'et' in the 'orbitdata' list
            # of 'ets' that is closest to the 'date' in the 'userdates'
            et = spice.str2et(date)
            dx = ets.index(getclosest(ets, et))

            # -- Outer frame -------------------------------------------------

            # Opacity of degree frame and Venus graphic
            frame_op = 0.8

            # Process calendar time strings
            date = '{} {}'.format(spice.et2utc(et, 'ISOC', 0).split('T')[0],
                                  spice.et2utc(et, 'ISOC', 0).split('T')[1])
            edate, etime = date.split()
            eyear = "{}".format(edate.split('-')[0])
            emonth = "{0:02d}".format(int(edate.split('-')[1]))
            eday = "{0:02d}".format(int(edate.split('-')[2]))
            epoch = "{}/{}/{}".format(eday, emonth, eyear)
            ep_name = "{}{}{}_{}".format(eyear, emonth, eday,
                                         etime.replace(':', ''))

            frame = _outerframe(epoch, frmSize=master_scale, frm_op=frame_op)

            # -- First Point of Aires ----------------------------------------

            # merc_loan = 48.331
            # merc_argp = 29.124
            arend = svg.make_marker("fopa_arrowend", "arrow_end",
                                    fill_opacity=0.4)

            x1, y1 = 10, 0
            x2, y2 = master_scale * 1.3, 0

            fpoa = svg.Line(x1, y1, x2, y2, stroke_width=".4pt",
                            stroke_opacity=0.4, arrow_end=arend)

            xp = (x2 * math.cos(math.radians(rotang)) -
                  y2 * math.sin(math.radians(rotang)))
            yp = (x2 * math.sin(math.radians(rotang)) +
                  y2 * math.cos(math.radians(rotang)))

            fpoa_text = svg.Text(xp + 6.5, yp - 1.0, "First Point of Aries",
                                 font_size=3, opacity=0.75)
            fpoa = svg.Fig(svg.Fig(fpoa, trans=svg.rotate(rotang, 0, 0)),
                           fpoa_text)

            # -- Some containers ---------------------------------------------

            orbs = []
            circles = []
            defs = svg.SVG("defs")

            # -- Orbit circles -----------------------------------------------

            # Build the SVG for each orbit.
            for orbit in orbits:

                if orbits.index(orbit) == 1:
                    orbit_op = 0.4
                else:
                    orbit_op = 1.0

                # Mercury's orbit will have perihelion on the X-axis
                circles.append(svg.Fig(svg.Poly(orbit, stroke_width=".25pt",
                                                stroke_opacity=orbit_op),
                                       trans=svg.rotate(rotang, 0, 0)))

            # -- Planet orbs -------------------------------------------------

            points = [orbits[0][dx], orbits[1][dx], orbits[2][dx]]

            # Build the planet orb for each planet for this chart.
            for point in points:

                # Planetary inputs ...
                if points.index(point) == 0:
                    name = "MERCURY"
                    nu = math.degrees(math.atan2(point[1], point[0])) + rotang
                    if nu < 0:
                        nu = nu + 360
                    # print(nu, nu-rotang, rotang)
                    nu = "{0:03d}".format(int(nu))
                if points.index(point) == 1:
                    name = "VENUS"
                if points.index(point) == 2:
                    name = "EARTH"

                # point_r  = [x/AU for x in point]

                orb, grad = _planetdiag(name, point, rotang)

                orbs.append(orb)
                defs.append(grad)

            # -- Build final figure ------------------------------------------

            wa = master_scale * 1.5
            svgout = svg.Fig(fpoa, frame,
                             circles[0], circles[1], circles[2],
                             orbs[0], orbs[1], orbs[2]
                             ).SVG(svg.window(-wa, wa, -wa, wa))

            svgout.prepend(defs)
            out_path = os.path.join(outdir,
                                    "merc_orbit_plot_{}_{}.svg".format(
                                        ep_name, nu))
            svgout.save(out_path)
            output_files.append(out_path)

        spice.kclear()

        return output_files

    else:
        # You'll jump to hear if the epochs for all 3 planets are not equal.
        print("There is an epoch error between the planet time values...")
示例#5
0
def ex1():
  angle_axis = svgfig.LineAxis(5, 0, 5, 2*pi, 0, 2*pi, stroke='white', text_attr={'fill':'white'})
  angle_axis.text_start = -2.5
  angle_axis.text_angle = 180.
  angle_axis.ticks = [x*2*pi/8 for x in range(8)]
  angle_axis.labels = lambda x: "%g" % (x*180/pi)
  angle_axis.miniticks = [x*2*pi/8/9 for x in range(8*9)]

  radial_axis = svgfig.XAxis(0, 5, aty=pi/2, stroke='white', text_attr={'fill':'white'})
  radial_axis.text_start = 5
  radial_axis.text_angle = 90.
  radial_axis.ticks = range(5)

  points = [(max(0.5, random.gauss(2.5, 1)), random.uniform(-pi, pi), max(0.1, random.gauss(0.3, 0.1))) for i in range(10)]
  xerr = svgfig.XErrorBars(points, stroke='white')
  yerr = svgfig.YErrorBars(points, stroke='white')
  dots = svgfig.Dots(points, svgfig.make_symbol("name", stroke="white", fill="red", stroke_width="0.25pt"))
  xml = svgfig.Fig(svgfig.Fig(angle_axis, radial_axis, xerr, yerr, dots, trans="x*cos(y), x*sin(y)")).SVG(svgfig.window(-6, 6, -6, 6)).standalone_xml()
  return QtCore.QByteArray(xml)
示例#6
0
def render( p ):
	return svgfig.Fig(svgfig.Poly(p.data) ).SVG(svgfig.window(p.min_x()-1,p.max_x()+1,p.min_y()-1,p.max_y()+1)).inkview()
示例#7
0
    def draw(self,
             filename,
             graphshape=None,
             width=1280,
             height=720,
             show_labels=False):
        """This does the drawing. It starts by getting a function for the bottom
    most layer. As descrbed in Byron & Wattenberg this will control the overall
    shape of the graph. It then it prints a stacked graph on top of that bottom 
    line, whatever shape it is.  
    """

        # Preprocess some stuff
        aspect_ratio = float(width) / float(height)
        self.canvas_aspect = aspect_ratio
        x_offset = int(-((100 * aspect_ratio) - 100) / 2.0)

        # Get a g_0 depending in desired shape
        g_0 = self.themeRiver()  # Default (fallbacks)
        y_offset = 0
        if str(graphshape) == "Stacked_Graph":
            g_0 = self.stackedGraph()
            y_offset = 0
        if str(graphshape) == "Theme_River":
            g_0 = self.themeRiver()
            y_offset = -50
        if str(graphshape) == "Wiggle":
            g_0 = self.wiggle()
            y_offset = -50
        if str(graphshape) == "Weighted_Wiggle":
            g_0 = self.weighted_wiggle()
            y_offset = -50

        # Initilize a streamgraph groups in SVG.
        graph = svgfig.SVG("g", id="StreamGraph")
        labels = svgfig.SVG("g", id="Labels")

        # Initilize a SVG Window object to do the transormations on each object
        window = svgfig.window(self.x_min, self.x_max, 0,
                               self.y_max * 1.3, x_offset, y_offset,
                               int(100 * aspect_ratio), 100)

        # Loop through each layer
        for layer in range(self.n_layers):
            points = []
            point_range = range(self.n_points)
            # Forwards; draw top of the shape
            for i in point_range:
                x = self.data[layer][i][0]
                y = self.data[layer][i][1]
                # Start with g_0 and stack
                y_stacked = g_0[i] + y
                # Stack!
                for l in range(layer):
                    y_stacked += self.data[l][i][1]
                # Add the points to the shape
                points.append((x, y_stacked))
            # Backwards; draw bottom of the shape
            #point_range.reverse()
            point_range = reversed(point_range)
            for i in point_range:
                x = self.data[layer][i][0]
                # This time we don't include this layer
                y_stacked = g_0[i]
                # Stack!
                for l in range(layer):
                    y_stacked += self.data[l][i][1]
                points.append((x, y_stacked))
            # Shapes
            poly = svgfig.Poly(points,
                               "smooth",
                               stroke="#eeeeee",
                               fill=self.rgb2hex(self.colors[layer]),
                               stroke_width="0.05")
            graph.append(poly.SVG(window))
            if show_labels:
                #label = self.placeLabel(points, layer)
                #label = self.test_placeLabel(points, layer)
                #label = self.test2_placeLabel(points, layer, window)
                label = self.placeLabel2(points, layer)
                #for l in label:
                #  labels.append(l)
                labels.append(label.SVG(window))
        # End Loop

        # Add objects to the canvas and save it
        w = str(int(width)) + "px"
        h = str(int(height)) + "px"
        canv = svgfig.canvas(graph, labels, width=w, height=h)
        canv.save(filename)
def render(p):
    return svgfig.Fig(svgfig.Poly(p.data)).SVG(
        svgfig.window(p.min_x() - 1,
                      p.max_x() + 1,
                      p.min_y() - 1,
                      p.max_y() + 1)).inkview()
示例#9
0
def ex1():
  angle_axis = svgfig.LineAxis(5, 0, 5, 2*pi, 0, 2*pi, stroke='white', text_attr={'fill':'white'})
  angle_axis.text_start = -2.5
  angle_axis.text_angle = 180.
  angle_axis.ticks = [x*2*pi/8 for x in range(8)]
  angle_axis.labels = lambda x: "%g" % (x*180/pi)
  angle_axis.miniticks = [x*2*pi/8/9 for x in range(8*9)]

  radial_axis = svgfig.XAxis(0, 5, aty=pi/2, stroke='white', text_attr={'fill':'white'})
  radial_axis.text_start = 5
  radial_axis.text_angle = 90.
  radial_axis.ticks = range(5)

  points = [(max(0.5, random.gauss(2.5, 1)), random.uniform(-pi, pi), max(0.1, random.gauss(0.3, 0.1))) for i in range(10)]
  xerr = svgfig.XErrorBars(points, stroke='white')
  yerr = svgfig.YErrorBars(points, stroke='white')
  dots = svgfig.Dots(points, svgfig.make_symbol("name", stroke="white", fill="red", stroke_width="0.25pt"))
  xml = svgfig.Fig(svgfig.Fig(angle_axis, radial_axis, xerr, yerr, dots, trans="x*cos(y), x*sin(y)")).SVG(svgfig.window(-6, 6, -6, 6)).standalone_xml()
  return QtCore.QByteArray(xml)
示例#10
0
  def draw(self, filename, graphshape = None, width = 1280, height = 720, show_labels = False):
    """This does the drawing. It starts by getting a function for the bottom
    most layer. As descrbed in Byron & Wattenberg this will control the overall
    shape of the graph. It then it prints a stacked graph on top of that bottom 
    line, whatever shape it is.  
    """
    
    # Preprocess some stuff
    aspect_ratio = float(width) / float(height)
    self.canvas_aspect = aspect_ratio
    x_offset = int( -((100 * aspect_ratio) - 100) / 2.0 )

    # Get a g_0 depending in desired shape
    g_0 = self.themeRiver() # Default (fallbacks)
    y_offset = 0
    if str(graphshape) == "Stacked_Graph" : 
      g_0 = self.stackedGraph()
      y_offset = 0
    if str(graphshape) == "Theme_River" : 
      g_0 = self.themeRiver()
      y_offset = -50
    if str(graphshape) == "Wiggle" : 
      g_0 = self.wiggle()
      y_offset = -50
    if str(graphshape) == "Weighted_Wiggle" : 
      g_0 = self.weighted_wiggle()
      y_offset = -50

    # Initilize a streamgraph groups in SVG.
    graph = svgfig.SVG("g", id="StreamGraph")
    labels = svgfig.SVG("g", id="Labels")

    # Initilize a SVG Window object to do the transormations on each object
    window = svgfig.window(self.x_min, self.x_max, 0, self.y_max * 1.3, x_offset, y_offset, int(100 * aspect_ratio), 100)

    # Loop through each layer
    for layer in range(self.n_layers):
      points = []
      point_range = range(self.n_points)
      # Forwards; draw top of the shape
      for i in point_range:
        x = self.data[layer][i][0]
        y = self.data[layer][i][1]
        # Start with g_0 and stack
        y_stacked = g_0[i] + y
        # Stack!
        for l in range(layer):
          y_stacked += self.data[l][i][1]
        # Add the points to the shape
        points.append((x, y_stacked))
      # Backwards; draw bottom of the shape
      point_range.reverse()
      for i in point_range:
        x = self.data[layer][i][0]
        # This time we don't include this layer
        y_stacked = g_0[i]
        # Stack!
        for l in range(layer):
          y_stacked += self.data[l][i][1]
        points.append((x,y_stacked))
      # Shapes  
      poly = svgfig.Poly(points, "smooth", stroke="#eeeeee", fill=self.rgb2hex(self.colors[layer]), stroke_width="0.05")
      graph.append(poly.SVG(window))
      if show_labels:
        #label = self.placeLabel(points, layer)
        #label = self.test_placeLabel(points, layer)
        #label = self.test2_placeLabel(points, layer, window)
        label = self.placeLabel2(points, layer)
        #for l in label:
        #  labels.append(l)
        labels.append(label.SVG(window))
    # End Loop

    # Add objects to the canvas and save it
    w = str(int(width)) + "px"
    h = str(int(height)) + "px"
    canv = svgfig.canvas(graph, labels, width=w, height=h)
    canv.save(filename)