Creating SVG graphics using svgwrite

Before we close this chapter, let's take a look at how to generate SVG graphics that are based on vectors and computer-drawn lines and shapes that are scalable. To do this, we are going to use a Python library called svgwrite, which you can find here: https://pypi.python.org/pypi/svgwrite. Since this is a Python library on PyPi, we can use pip to install it.

For Windows users using VSPT

Add your current Python instance to your Python environments in your Solution Explorer and type in svgwrite in the Install Python Package prompt as shown in the following screenshot:

For Windows users using VSPT

If successful, you should see the packages in your Solution Explorer as shown in the following screenshot. If you can't see them, try opening your Python Environments, and then your version of Python in your solution:

For Windows users using VSPT

For Eclipse or other editors on Windows

Type in the following command in your command prompt with admin rights:

cd C:Python27
pip install svgwrite

The following is a screenshot of a command prompt for Windows:

For Eclipse or other editors on Windows

For Eclipse on Mac and Linux

Open the terminal and type in the following command:

sudo pip install svgwrite

We are using sudo here to ensure everything for svgwrite has been installed properly. Next, create your project in PyDev and be sure to set the project path to src. This sets the path to its own directory rather than your Python root. Have a look at the following screenshot showing the start of a new PyDev project in Eclipse on OS X:

For Eclipse on Mac and Linux

In Eclipse, you can also inspect code using the Python console. In your console, click on the New Console View icon at the top-right of the window and select Pydev Console as shown in the following screenshot:

For Eclipse on Mac and Linux

You can also verify in PyDev what packages you have installed. In your PyDev Package Explorer, expand the python root and go to System Libs | 2.7/site-packages. Once open, if you can find svgwrite, you should be set. In the following screenshot, you can see how it looks on my system:

For Eclipse on Mac and Linux

Once you're ready, we will create a new project and Python file to generate our SVG file. Start by creating an import of svgwrite (in lowercase) as shown in the following code:

import svgwrite

Now let's reference the root svgwrite library and assign it to a variable that we can output as an SVG file. For this, we will use the Drawing method in svgwrite. The Drawing method enables us to create an SVG file. It's where we will drop our other objects such as text, lines, circles, and so on.

Let's take a look at the following example:

drawObj = svgwrite.Drawing('username.svg', profile='tiny', width=444, height=300)

Here, we have a drawObj variable and we have created an instance of the svgwrite object and called the Drawing method with a few parameters. Our first parameter is a string where we declare our filename; in this case, username.svg. Note that we are not including a path, so for this script, the file will be saved in our project directory.

The profile attribute sets the base profile for SVG. You have two values that you can use: tiny and full. We can also set the width and height of the SVG tag with the width and height attributes.

Now, we have the base drawing object to draw shapes on. We will append the drawObj variable with an SVG text node. Take a look at the following line:

drawObj.add(drawObj.text('Test', insert=(0, 0), fill='red', font_size=70, font_family='sans-serif', font_weight='bold'))

So here we have a series of parameters for our line. The first is a string for the text copy we want to write into the node and the next is a map (a map is a group of two parameters). This map sets the X and Y coordinates for our top-left text block element in the SVG node.

Following that is our fill color for this text block; in this case, we have a value of red. We can also use hex values here if we need it to be similar to a color hex in CSS. We also have three more parameters here: font_size, font_family, and font_weight, all of which are pretty self-explanatory. The font_size parameter uses simple int values to increase or decrease size. The font_family parameter will work with any regular font included on the system (no file path needed). And font_weight can set the font's weight to be bold or light depending on the selected font's properties. Take note, without the font_family parameter, the font_weight parameter will not work.

Lastly, we will save the drawObj variable to a file using the save() function. This will save the file with the parameters we added. With that added, here's a completed script ready to run. Here's our save() function:

drawObj.save()

Now let's run the application from our IDE. Check your code as you follow along with the drawObj sample shown in the previous code, and assuming no errors are encountered, you should see a terminal (or a command prompt) window with Press Enter to continue… displayed just like the previous example, indicating success.

We can check this by going into our project directory and opening our newly generated username.svg file in our browser of choice and taking a look:

For Eclipse on Mac and Linux

We're almost there. It looks like our SVG file is fine, but our text node is off-center. Remember our insert map, where we defined our X and Y coordinates? Let's tweak that; also, if you are working on Ubuntu or any other Linux distro, you may need to format the X and Y coordinates to fit your platform's browser:

drawObj.add(drawObj.text('Test', insert=(15, 64), fill='red', font_size=70, font_family='sans-serif', font_weight='bold'))

Let's rerun and refresh our SVG file in our browser:

For Eclipse on Mac and Linux

There is our text, showing up as an SVG we generated. Note that we can even select the text. Since this is a text node, we should be able to highlight and even search it inside the web content. Having the output as SVG gives us a range of uses to create graphics.

Let's add a few lines around our text node, like an X and Y chart baseline, just to show some basic drawing. Before your save() function, include the line() functions as shown in in the following example:

import svgwrite

drawObj = svgwrite.Drawing('username.svg', profile='tiny', width=444, height=300)
drawObj.add(drawObj.text('Test', insert=(15, 64), fill='red', font_size=70, font_family='sans-serif', font_weight='bold'))
drawObj.add(drawObj.line((10, 10), (10, 70), stroke=svgwrite.rgb(0, 0, 0, '%')))
drawObj.add(drawObj.line((10, 70), (370, 70), stroke=svgwrite.rgb(0, 0, 0, '%')))
drawObj.save()

Now let's rerun our project and take a look at the results:

For Eclipse on Mac and Linux

Now we have the start of what would be a very simple chart exported as an SVG file that we can manipulate in HTML (using an SVG-compliant browser). Take a look at the following screenshot. Here, we can change the fill color using Chrome's Web Inspector:

For Eclipse on Mac and Linux

Neat! So now we can print text and objects to an SVG file! We can draw lines, boxes, and circles in SVG, and as you see this come along, you start to get an idea how to build charts and graphs from scratch. Let's make this script a bit more functional, as though we were using this as an application. Let's reuse our text file reader module from our Hello World image script.

Before starting with this code, ensure your content.txt file is at the root of your project directory. Next, let's reuse our readcontent() function from our earlier script. Breaking up that code in a module early on helps us reuse the code in new projects by copying and pasting!

Firstly, include your imports, which will contain svgwrite, just like before to access your text file:

import svgwrite

def readcontent():
    '''Open the file to be read. Note the file's permission is set to read-only.'''
    openFile = open('content.txt', 'r')
    '''Save the file's inner content to a Python Variable string.'''
    readmeText = openFile.read()
    '''Close the file to save memory.'''
    openFile.close()
    '''Return the results to each as a reference variable.'''
    return openFile, readmeText

'''trigger the read content function.'''
openFile, readmeText = readcontent()

Now let's wrap our svgwrite in its own function and give it a parameter; in this case, username, to pass our content.txt file's output. Your Python script should resemble the following code:

import svgwrite
def readcontent():
      '''Open the file to be read. Note the file's permission is set to read-only.'''
      openFile = open('content.txt', 'r')

      readmeText = openFile.read()
      '''Save the file's inner content to a Python Variable string.'''

      openFile.close()
      '''Close the file to save memory.'''

      return openFile, readmeText
      '''Return the results to each as a reference variable.'''


def createSVGText(usrname):
    drawObj = svgwrite.Drawing('username.svg', profile='tiny', width=444, height=300)
    drawObj.add(drawObj.text(usrname, insert=(15, 64), fill='red', font_size=70, font_family='sans-serif', font_weight='bold'))
    drawObj.add(drawObj.line((10, 10), (10, 70), stroke=svgwrite.rgb(0, 0, 0, '%')))
    drawObj.add(drawObj.line((10, 70), (400, 70), stroke=svgwrite.rgb(0, 0, 0, '%')))
    drawObj.save()
    return drawObj

'''trigger the read content function.'''
openFile, readmeText = readcontent()
'''Grab the 'readmeText' file content and pass that into our createSVGText function.'''
drawObj = createSVGText(readmeText)

Rerun the script and let's take a look at our username.svg file:

For Eclipse on Mac and Linux

There we are! We have created a dynamic script that pulls in data from a local text file and imports it into a chart-like layout and updates dynamically for each run. Play around with the options and see what you can make, and type other words into the content.txt file.

Now this is still a simple script; obviously, if we type in a very long string in our text file, it will overflow the SVG file. This is just one element. What if you were building a chart from scratch and needed everything to work properly? We can assume this will only get more and more complex, and ultimately that is the point of this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.115.155