I'm struggling with a rather straight forward operation - rotating a bone. There are tons of examples but can't seem to get it working.

I need to rotate the bone in edit mode (if it's mode specific please share the method too).

I think my selection isn't working. Below is my code:

bpy.context.object.data.bones.active = bpy.context.object.pose.bones["lowerarm_l"].bone
bpy.context.object.data.bones.active.hide = True


  • $\begingroup$ Right now, I cannot answer your question. As far as I can tell you're executing all these lines one by one via the Python command line. Please try to understand what each line is supposed to do first, identify where (i.e. at which of these lines) your code behaves differently than you'd expect and then ask a more specific question. $\endgroup$ Commented Jun 10, 2020 at 13:54
  • $\begingroup$ You're using the bones in pose mode, use ob.data.bones. $\endgroup$ Commented Jun 10, 2020 at 14:05

2 Answers 2


Rotate an edit bone

To define a rotation require the angle to rotate, the axis to rotate around and a point that the axis goes thru. To code transforms in 3D the sooner we get our heads around linear algebra, ie vectors and matrices the easier it becomes.

Following test script rotates the edit bone (in edit mode) named "Bone" 30 degrees around the bones local X axis, using its head as the pivot point.

One translation matrix moves such that the head is (0, 0, 0) our pivot point. Rotate this with rotation matrix. Move back with negated transform matrix.

import bpy
from mathutils import Matrix
from math import radians

context = bpy.context

bone_name = "Bone" # change to suit

ob = context.edit_object
arm = ob.data

#bone = context.active_bone
bone = arm.edit_bones.get(bone_name)

if bone:
    # local axes of the bone
    x, y, z = bone.matrix.to_3x3().col
    # rotation matrix 30 degrees around local x axis thru head
    R = (Matrix.Translation(bone.head) @
         Matrix.Rotation(radians(30), 4, x) @
    #bone.matrix = R @ bone.matrix

adjust the angle, the axis, the pivot point to demo how it works. Using y for axis should "roll" the bone.

  • $\begingroup$ Thanks, however it doesn't work with the Z axis instead of X, the bone is going crazy. $\endgroup$
    – lucky3
    Commented Sep 29, 2020 at 17:30

From @batFinger code, fix to make it work with all axes:

import bpy
from mathutils import Matrix
from math import radians    

bone = bpy.context.selected_editable_bones[0]

if bone:
    old_head = bone.head.copy()
    R = Matrix.Rotation(radians(30), 4, bone.x_axis.normalized())   
    bone.transform(R, roll=True) 
    offset_vec = -(bone.head - old_head)
    bone.head += offset_vec
    bone.tail += offset_vec

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .