So far in the Data Visualisation Series in Blender, we've created horizontal bar graphs, vertical bar graphs and bar graph races. We're leaving the world of bars for the world of pies and pi.
You'll be happy to note that the script for a basic pie graph is much shorter than our previous scripts for bar graphs. The concept will be new, as well as the syntax but I've taken the time to explain the functions that we will use and the logic behind the script that we'll make here. But, as always, you're welcome to send me an email if you have questions.
Section 1. Importing modules
We'll need a few modules for our script. The two modules that we have imported are simply the Blender API and the random module that we will use to generate random numbers for random colours for materials later on. Thankfully the ones we need are already installed so all we have to do is import them in as follows:
Section 2. Defining a text function
In this section we are going to create a function that allows us to easily clean our text objects. We have used this previously in the earlier parts of this series. For those of you have seen this before there is nothing new here but for those who require an explanation there is one after the code snippet.
The first line adds a text object and puts us into edit mode. The second line deletes the default string from the text object. The third line types out the text that we wish for the text object to display. After that we toggle out of edit mode, back into object mode and then we sat our origin to the geometry of our text object. We do this so the origin is at the middle of the text object and not in the lower left-hand corner of the first letter.
Section 3. Defining data
Next we define some of our data values, we can do this in a list. We are also going to use list comprehensions to calculate what our string values should be for the percentage labels of each slice of our pie chart.
We've listed out data as decimal values for the math that we'll do later on. Our pieLabels list takes each element of data and times it by 100, converts it to a string and adds the '%' symbol. We'll use these values later for generating labels in our pie chart.
Section 4. Calculating positions and rotations
The approach we're using here to generate a pie chart is to pivot planes using euler math and extruding using Blender's native Spin tool which can be found in edit mode. We need to use Spin specifically because the usual Extrude tool in Blender doesn't extrude at angles.
The slice list comprehension calculates the fraction of a circle that each value of data geometrically represents. The rot list comprehension calculates the starting position of each of the slices which we will use to spin planes out from. The rotation values are negative because we are going to spin the slices out in a clockwise direction.
Section 5. Defining values
Next, we're going to define some simple values for the height of our pie slices and the sizes of our titles and labels. Alter these to be whatever you like, these values are purely cosmetic and the actual logic of the code is not dependent on these variables.
pieHeight is the thickness of our slices.
titleY is the location of the graph title in the y-axis.
labelZ is the height of the labels on the z axis.
labelSize in the side of each label.
titleSize is the size of the title.
graphTitle is the string that the title object will display.
Section 6. Creating a title
In this section we can generate the title of our graph using the function that we defined at the beginning of the group, our graphTitle string and some basic bpy instructions.
The first line ensures that the cursor is at the origin. The second line calls our text cleanup and share in with graphTitle as our input. The third line then takes the generated text object and set set at the correct location. The final line then resizes the text object.
Section 7. The main loop
We're finally ready to begin scripting the main loop of our code. This is where we will generate the slices of our pie chart and create labels that will hover above each slice. I have split this loop into two sections. The first section that we will look at is the slice generator.
So to begin, our for loop will go through each value in data and execute the instructions with and for each value. The first line ensures that our cursor is at the origin, the second line then adds a plane and puts it into edit mode. We then resize our plane with our pieHeight value.
Our plane is then translated one unit up(y-axis) so that the bottom edge of our plane sits at the origin. We then rotate the plane so that it standing on its long edge and we set the origin of the object to be where our cursor is, which is on the origin. The bottom edge of our plane, which we want to pivot from, is also at this point. We set the origin of the plane object to be at the cursor to create the correct pivot point. We then make sure to rotate our plane by its corresponding start position in the rot list.
The plane is then extruded and we then apply the spin tool on that extrusion to create a slice for our pie graph. One thing to note is that in the last line there is a step argument which gives the number of subdivisions in the slice. Make this number high if your slices look too blocky.
Once our slices have been generated a corresponding label will also be generated. Firstly toggle into edit mode and make sure our origin inserts to the middle of the slice geometry. We then move the cursor to the location of the slice. We then call our txtCleanup function with the corresponding label in our pieLabels list as the argument. We then set the location of the generated text object to the location of the cursor, which is at the origin of our slice. We move our text object in the set to the location stored in labelZ. In the final line we resize the label object.
Section 8. Creating a text material
Congratulations! If you've made it this far then you've pretty much made all the basic geometry for your pie graph. At this point all we're going to do is start making some materials. If you've done the previous tutorials then all of this will look very familiar to you. To begin, we're going to create a black text material.
The very first line sets the cursor back to the origin. We then create a variable for a new material which we call labelMat and set the name of our material to 'Label Material' with the name argument. You can change this to be whatever you like. In the second line we take the material that we created and we give it the colour black. In the final line we use a list comprehension to apply this new material to all text objects.
Section 9. Generating random slice materials
In this final section were going to create materials for the slices of our pie graph. We're going to randomly generate RBG values using the random module that we imported at the beginning of the script.
The first line is a for loop declaration which searches through every object in scene. The second line is an if statement that retrieves the names of every object that have the word 'Plane' in them. Note, this is case sensitive. The first line within our if statement creates a new material which we store in a variable called currentMat. In the name argument I have added obj.name at the end so currentMat will generate a new material with a sensible name for each object each time the for loop iterates. The second line then generates a random colour for our current material and the final line applies it to our current object.
A final word from Kit
Thank you to everyone who read this tutorial. I hope that anyone who tried it found it useful. I have left an example render of the pie graph below for your interest, and a copy of this tutorial for download. If you have any questions you are quite welcome to send me an email at the following address: steambeanblog@gmail.com
I hope everyone is doing well and staying safe at this time. :)
Appendix