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.
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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.
18.188.115.155