Working with Imported Data

DM01_0Header

I wanted to take the time to show an example of using Grasshopper to work with data imported from a source outside of Rhino, such as a spreadsheet developed in Excel. Importing data from outside sources is also fundamental to more advanced interactions, such as having the program communicate with remote machines or sensors.

In this example, I wanted to make a diagram of a river’s watershed abstracting the spatial relationship of the river’s tributaries and showing how much each tributary contributes to the overall river’s flow. The technical name for this type of diagram is a “Sankey Diagram”. I actually drew one of these initially in Illustrator, which is superior to rhino/Grasshopper in many ways for representation, but it was a very time consuming process, and if I wanted to create a similar diagram for another watershed, I would have to start from scratch. Another drawback of drawing this in Illustrator is if a datapoint or datapoints change, it can be a time-consuming process to update this. It is also a static representation, and as we all know, a river’s flow is dynamic and changing. Having a representation or diagram that can automatically update with changing values, in this case flow in the individual tributaries, can be a very powerful form of representation.

There are a number of tools and plugins that can deal with importing data into grasshopper, but for this example I will use one of the native tools to the program, and then draw some geometry based on the dataset.

Preparation – Collect and Organize Data

The first step is probably the most time-consuming, to actually collect data that could be useful for your diagram. In this case, I researched using Wikipedia all of the tributaries of the River Leine in central Germany, which happens to flow right behind my house. I was able to get the length and watershed area for each tributary, and measured at what river kilometer each tributary branched. Further, I noted whether it was a left- or a right-branching tributary. I was able to get the average discharge of some of the branches, but not all, so I decided I would estimate discharge based on the area of collection, for the purposes of this example.

I compiled all of this data into an Excel file. There are some plugins that can import Excel tables (e.g. Howl + Firefly), but maybe a simpler way is to Export your Excel file as a *.csv file (Comma separated variable), and then to save this file again using a text editor as a *.txt file.

If you would like to follow along in this example, you can copy the following and save it as a *.txt file

R,Grindau,6.1,26,11,35
R,Grosse Beeke ,12,26,5,30
R,Juersenbach,18.9,26,6,49
R,Auter,24,26,10,113
L,Totes Moor,59.7,26,8,56
L,Westaue,72.2,35,38,600
L,Foesse,94.5,53,8,20
L,Ihme,99.5,48,16,110
R,Innerste,121.5,58,99.7,1264
L,Gestorfer Beeke,125.4,58,8,13
R,Roessingbach,125.5,58,14,36.3
L,Haller,132.8,70,20,124
L,Saale,138.5,73,25,202
R,Despe,142.1,74,12,47
L,Glene,153.1,74,11.7,40
R,Warnebach,156,74,8,27
L,Wispe,161.7,74,22,74
R,Gande,175.6,74,41,114
R,Aue,177.7,103,23,113
L,Ilme,186.5,105,32.6,393
L,Boelle ,191.9,110,10,21
R,Rhume,192.8,116,48,1193
L,Moore,198,118,11,43
R,Beverbach,206.9,120,14,35
L,Espolde,207.9,126,16.1,65
R,Rodebach,208.1,130,8,20
R,Weende,208.9,135,9.2,18.6
L,Harste,209.9,138,8.6,29
L,Grone,211.6,140,6,26
R,Lutter,211.7,144,8.1,38
L,Rase,219.3,150,9,23.8
R,Garte,219.4,152,23,87.2
R,Wendebach,223.4,162,16.2,36
L,Dramme,225,161,14.4,53
L,Molle,230,182,7,10
R,Schleierbach,232.4,191,6,15
R,Rustebach,236.8,210,8,13
L,Steinsbach,238.1,215,5,15
L,Lutter,244.7,233,7,21
R,Beber,245.4,237,7,30
L,Geislede,249.6,260,19,52
R,Steinbach,255.3,276,6,14
R,Etzelsbach,258.4,293,5,13
R,Liene,264.2,337,7,18

What you’ll notice is each line has a series of values, separated by a comma, which would correspond to each individual “cell” in Excel. Once this is done, you can move onto the next step.

Step One – Import Data

DM01_01

To import the data, we will use three components. The first is the “File Path” parameter, which feeds into the “Read File” component, in this case set to “Per Line”. Each line will get its own Index in GH. Then we use the “Split Text” component, with a simple comma symbol as the second input, which further structures our data splitting each line at each comma. I put panels behind the components for reference.

Step Two – Sort Data

DM01_02

What you do next is entirely situational, but before you start drawing geometry, you may need to reorganize and/or restructure data so it will be useful to you. In this case, there is not too much restructuring necessary, I just wanted to split my dataset into two subsets based on whether the tributaries head left or right, since we will be drawing those differently. In this case , I list the first Item 0, and then distribute the list based on whether the data is in a Left Branch or a Right Branch. The distribute component needs a true/false value, so to get around this problem, I simply replaced my R’s and L’s with True’s and False’s. In this case I needed to also remove empty branches using the “Remove Branch” component.

The general idea, however, is you may need to play around with your inputs and/or data structure to get something which is most helpful to you.

Step Three – Draw Basic Skeleton

DM01_03.PNG

Before we get too crazy, it is useful to draw only the basic skeleton of our system based on our data. Basically you will be using a lot of “List Item” components to call out your data, and then draw geometry in GH based on this. I recommend grouping your list Items and labelling them to help you keep track of what is what, otherwise you will soon be left with a confusing mass of spaghetti. Well the spaghetti might be inevitable, but labelling always helps when you need to make some changes!

Step Four – First Refinements 

DM01_04.PNG

Once we have our basic skeleton, its time to start gradually refining the process. In this case, I eventually want to show each tributary with a varying thickness based on how much water it contributes to the river system. As mentioned previously, this will be a factor of “watershed area” as a rough approximation of water volume contributed. I first list watershed area for each tributary, divide by a factor, and then want to progressively move the tributaries towards the Right (i known, they are left tributaries, but left in the sense of a boat traveling downstream…if you are traveling upstream, which we are in this case, it would be on your right. hope i’m not confusing you. Think Left Bank in Paris if that helps).

The mass addition component comes in very helpful here for both calculating the total area of all the branches, and also progressively telling you how they add up. One small thing we need to do is in order to get the branches to move correctly, we need to subtract the Step values from the Total value so the branches will get the proper “X” vector.

Step Five, and so on….  Further Refinements…

DM01_06

I won’t explain all what’s going on here…These are all simple operations, to improve the graphic quality of our lines. I am doing a few arcs, but also placing text to label my diagram.

DM01_07s.PNG

Once we get close to what we want for the Left branches, we can copy and paste for the right branches. Notice we have to change a few of the vectors (positive to negative) to get the geometry to move and draw in the correct direction.

DM01_08

How far you want to go is up to you. Here I gave a line thickness using the “Sweep” command, sized the text proportionally based on tributary size (with a minimum text size for the smallest streams), and also made the arc radius proportional to the branch thickness. This is all pretty simple to do, but the GH script can get a bit messy.

Further Steps – Using Script with a New Data Set and Changing Values

DM01_09

Once you have a working process setup, you can plug in new datasets, as long as they are structured the same as the dataset you used to create your script, to do another graphic diagram. Here I researched the same values for the Ems River (on the border between Germany and Netherlands). The research took hours. Plugging the new values into GH and generating this diagram took less than five seconds.

DM01_09c

You can also update values, and the diagram will change. Say you wanted to compare a river’s discharge at different times of the year, or even have a diagram that updated based on real time sensors. This is possible, and when the file GH is reading is re-saved, the diagram updates automatically, even without you doing anything in GH. Here I randomly changed some of the values of the tributaries of the Aller River in Germany (of which the Leine, which we previously diagrammed, is the largest tributary) and you can see how the diagram updates in real time.

Anyways, this is just meant as an introduction to the topic, but if you anticipate doing a drawing that you may need to replicate again in the future, are dealing with changing data values, or if you are simply toying around with the representation of a large dataset, a scripted environment may be a good way to approach this task.

 

 

Advertisements