# How do I modify this script to affect bones instead of shape keys?

import bpy
import csv
import numpy as np
data_path = 'C:/Users/E/Desktop/example.csv'
ob = bpy.context.object

with open(data_path, 'r') as f:
shapekeys = ob.data.shape_keys.key_blocks
for i in range(data.shape[0]):
if data[i][1] != '0':

for shape in shapekeys:
if shape.name in names:
index = names.index(shape.name)
shape.value=float(data[i][index])
shape.keyframe_insert("value", frame=i)

# The script does all the data mining to get the needed values.
# It allocates 3 values needed to utilize
# shape.name = bone name
# shape.value = location Y
# current frame = i
# I added these lines below but it doesn't work

pb = ob.pose.bones.get(shape.name)
if pb:
pb.location.y = shape.value
pb.keyframe_insert("location", i ) # y location


This script gives me an error "armature object has no attribute" So what is it that is needed to make this script allocate bone values locations Y?

• I don't understand what you are wanting to do. Are you trying to apply the pose of the bones to the mesh, and preserve the scaled armature shape as its new rest pose, but only the bones' y scale? – ZargulTheWizard Jan 18 at 18:17
• @ZargulTheWizard The data is from facial capture, but the way it's set up is it takes the data and applies it to the 60 shape keys directly. This is no good for me as I use bones as drivers to control those shape keys. So it need to apply the data not to the shape keys but to the 60 bones that have the same name as the shape keys instead. – Eric Huelin Jan 18 at 18:57
• Okay, it looks like you are wanting to convert shape key results to pose results. As for me, I don't know if that's possible (like converting from bitmap to purely vector graphics), but it might be. Is this what you are doing? – ZargulTheWizard Jan 20 at 2:49
• @ZargulTheWizard No. I don't want any poses results I just want bone translation. The bones are just a row of bones that move up and down equal to the shape key values. – Eric Huelin Jan 21 at 13:51
• So... You want to link the shape key strength/value to the scale of the bones? – ZargulTheWizard Jan 21 at 22:55

Something like?

Speculating that the data file is akin to

name value
Bone 10.0
Bone.001 22


and using a string to emulate the file, ie data.splitlines() to emulate a text file buffer. Example below, pose bone "Bone" keyframe location 0 at frame 0,
Run script with the armature object active and not in edit mode.

import bpy
import csv

context = bpy.context
ob = context.object
frames_per_line = 20

data = '''Bone, 0
Bone.001, 0.4
Bone.002,  1.0
Bone, 10
Bone, 20
Bone.002, -2.9'''

for frame, (name, value) in enumerate(csv.reader(data.splitlines())):

pb = ob.pose.bones.get(name)
if pb:
pb.location.y = float(value)
pb.keyframe_insert(
"location",
index=1,
frame=frames_per_line * frame
) # y location

• It's very difficult for me to take your data and rearrange it to fit the actual data. If the bounty expires in 4 days can I still award it to you later than that limit? – Eric Huelin Jan 25 at 5:36
• It's very difficult without seeing the actual data. Consider editing question for a less speculative answer. – batFINGER Jan 25 at 6:05
• I don't mind providing more information if it helps. The data is parsed by the existing script but the destination is different. Within the last 3 lines gives the needed information to transform the script: index = boneName, shape.value = Yloc, i=keyframe. I just have to add new lines where the bones get that info instead. That is what I was hoping would happen. But I had to study the script to understand this since I rarely use Python. – Eric Huelin Jan 26 at 1:24
• To put this another way, on your computer with a text editor open the file C:/Users/E/Desktop/example.csv copy and paste some rows into question. – batFINGER Jan 27 at 6:43
• I updated the question. You don't need the datafile the script finds all the data needed. I added part of your snippet but I need a bit more code to make it work with your help please. – Eric Huelin Jan 28 at 0:57