# Data Visualization - Iterate through a Collection of objects and set Z scale to a value from a specific csv file column index

Summary: Scale height of 77 mesh objects, by a csv file column with 77 float values.
*iterate through csv column drop head and save row value to list.
*iterate through objects in collection and apply Z scale from respective csv column row

Hello, I'm swirling now and can't seem to lock in my code. I am working on a data visualization map project and attempting to scale parts of a map in relation to a column of values in a csv file. I have 77 custom mesh objects in a collection and all of their origins are set to bottom surface center (for the purpose of scaling their height. Respectively, I have a csv file with column values with 77 rows. Each column has different stats, so I can change the index and get a different height map. I successfully can iterate over my csv file and see the correct values in a list. Now, I'm having trouble iterating through my "77 objects" in my collection and assigning the correct row value to each object. I have looked at '[3pointedit][1]' similar question, but it doesn't address my specific workflow and I tried the code and I had trouble getting it to apply. I understand I have a counter in the 'for loop' I probably don't need and maybe another variable holder, but I was just experimenting. If anyone has an idea, let me know! thanks!!!!

Here is my current (non-working) code. I don't mind selecting all my collection objects before I run it, if that helps.

import bpy
import csv
import numpy as np

with open('csv_file') as csv_file:

col_values = []
counter = 0

current_row_val = float(row[1])
col_values.append(current_row_val)
counter = counter + 1
current_value = row[:]

sel_objs = [obj for obj in bpy.context.selected_objects if obj.type == 'MESH']
bpy.ops.object.select_all(action='DESELECT')

if sel_objs:
obj1 = sel_objs.pop()
obj1.select = True
bpy.context.scene.objects.active = obj1
bpy.ops.transform.resize(value=(1.0, 1.0, float(current_value), orient_type='GLOBAL', orient_matrix=((0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0)), orient_matrix_type='GLOBAL', constraint_axis=(False, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1.0, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_target='CLOSEST', snap_point=(0.0, 0.0, 0.0), snap_align=False, snap_normal=(0.0, 0.0, 0.0), gpencil_strokes=False, texture_space=False, remove_on_cancel=False, center_override=(0.0, 0.0, 0.0), release_confirm=False, use_accurate=False)


# I updated my code. I get one object changing it's scale, but not all respectively.

import bpy
import csv
import numpy as np

# **make sure to set csv file path**
with open('..../test_csv.csv') as csv_file:

col_values = []
counter = 0

current_row_val = float(row[1])
col_values.append(current_row_val)
counter = counter + 1
current_value = row[:]
#print(current_row_val)

for object in bpy.context.selected_objects:
bpy.context.object.scale[2] = ((col_values[1]) + 1) / 10



# v03 Update. This code worked last night, but I may refine it based on user 'thorst' comments below.

import bpy
import csv
import numpy as np

# **make sure to set csv file path**
with open('..../test_csv.csv') as csv_file:

col_values = []
#counter = 0

#***************************^CHANGE_CSV_'column'row[]!
current_row_val = float(row[2])
col_values.append(current_row_val)
#counter = counter + 1
current_value = row[:]
print(current_row_val)

obj_counter = -1
for active in bpy.context.selected_objects:
obj_counter = obj_counter + 1
bpy.context.view_layer.objects.active = active

# **Change the multiple divide value below, so the bars look better!

# **FOR DATA BETWEEN 1000-100000 - sample 'Per Capita Income' INDEX 2!!!!!
bpy.context.object.scale[2] = (col_values[obj_counter] / 7000) * 3

[My github repo for this test file][2]

[1]: https://blender.stackexchange.com/questions/139160/how-to-use-csv-values-to-drive-object-scale
[2]: https://github.com/gitgranthub/blender_scale_objects_csv.git


object_no = 0
for object in bpy.context.selected_objects:
object.scale[2] = ((col_values[object_no]) + 1) / 10
object_no += 1


object is your iterator object which is defined via the for-loop

for object in bpy.context.selected_objects:


bpy.context.object is a separate variable in Blender's API and unaffected by the loop. It points to the same object in your scene in each iteration (probably the active one as it looks in a test I did with two cubes, but the API description doesn't clear this up). This is why you see one object changing and all the others stay the same.

Furthermore, you also need to iterate over the scaling-values from your ascii-table, this can be done with a second iterator variable object_no, initialised to the first entry before the loop and then increasing it at the end of each iteration.

• Thank you for looking at this! I will swap out some things and see if it works. I've updated the code above with a 3rd update of my code I got working last night. I made an object counter before the last loop. I'm not quite sure why I had to set it to -1 to get all my values to scale the objects. Maybe my head was not being skipped in the csv? – drivethrulake Jul 26 '20 at 1:10
• You have to start with -1 in your solution because you increase the counter by one before using it. So although you initialize it with -1, the first time it is used it is indeed 0. – thorst Jul 27 '20 at 4:10
• Thanks! The -1 counter makes sense now. – drivethrulake Jul 28 '20 at 14:07