text: def plot17j(poses, show_animation=False):
      import matplotlib as mpl
      mpl.use('Qt5Agg')
      import matplotlib.pyplot as plt
      import numpy as np
      import matplotlib.animation as anim
  
      from mpl_toolkits.mplot3d import axes3d, Axes3D
  
      fig = plt.figure()
  
      if not show_animation:
          plot_idx = 1
  
          frames = np.linspace(start=0, stop=poses.shape[0]-1, num=10).astype(int)
  
          for i in frames:
              ax = fig.add_subplot(2, 5, plot_idx, projection='3d')
  
              pose = poses[i]
  
              x = pose[0:16]
              y = pose[16:32]
              z = pose[32:48]
              ax.scatter(x, y, z)
  
              ax.plot(x[([0, 1])], y[([0, 1])], z[([0, 1])])
              ax.plot(x[([1, 2])], y[([1, 2])], z[([1, 2])])
              ax.plot(x[([3, 4])], y[([3, 4])], z[([3, 4])])
              ax.plot(x[([4, 5])], y[([4, 5])], z[([4, 5])])
              ax.plot(x[([0, 6])], y[([0, 6])], z[([0, 6])])
              ax.plot(x[([3, 6])], y[([3, 6])], z[([3, 6])])
              ax.plot(x[([6, 7])], y[([6, 7])], z[([6, 7])])
              ax.plot(x[([7, 8])], y[([7, 8])], z[([7, 8])])
              ax.plot(x[([8, 9])], y[([8, 9])], z[([8, 9])])
              ax.plot(x[([7, 10])], y[([7, 10])], z[([7, 10])])
              ax.plot(x[([10, 11])], y[([10, 11])], z[([10, 11])])
              ax.plot(x[([11, 12])], y[([11, 12])], z[([11, 12])])
              ax.plot(x[([7, 13])], y[([7, 13])], z[([7, 13])])
              ax.plot(x[([13, 14])], y[([13, 14])], z[([13, 14])])
              ax.plot(x[([14, 15])], y[([14, 15])], z[([14, 15])])
  
              # Create cubic bounding box to simulate equal aspect ratio
              max_range = np.array([x.max() - x.min(), y.max() - y.min(), z.max() - z.min()]).max()
              Xb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5 * (x.max() + x.min())
              Yb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5 * (y.max() + y.min())
              Zb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5 * (z.max() + z.min())
  
              for xb, yb, zb in zip(Xb, Yb, Zb):
                  ax.plot([xb], [yb], [zb], 'w')
  
              ax.axis('equal')
              ax.axis('off')
  
              ax.set_title('frame = ' + str(i))
  
              plot_idx += 1
  
          # this uses QT5Agg backend
          # you can identify the backend using plt.get_backend()
          # delete the following two lines and resize manually if it throws an error
          figManager = plt.get_current_fig_manager()
          figManager.window.showMaximized()
  
          plt.show()
  
      else:
          def update(i):
  
              ax.clear()
  
              pose = poses[i]
  
              x = pose[0:16]
              y = pose[16:32]
              z = pose[32:48]
              ax.scatter(x, y, z)
  
              ax.plot(x[([0, 1])], y[([0, 1])], z[([0, 1])])
              ax.plot(x[([1, 2])], y[([1, 2])], z[([1, 2])])
              ax.plot(x[([3, 4])], y[([3, 4])], z[([3, 4])])
              ax.plot(x[([4, 5])], y[([4, 5])], z[([4, 5])])
              ax.plot(x[([0, 6])], y[([0, 6])], z[([0, 6])])
              ax.plot(x[([3, 6])], y[([3, 6])], z[([3, 6])])
              ax.plot(x[([6, 7])], y[([6, 7])], z[([6, 7])])
              ax.plot(x[([7, 8])], y[([7, 8])], z[([7, 8])])
              ax.plot(x[([8, 9])], y[([8, 9])], z[([8, 9])])
              ax.plot(x[([7, 10])], y[([7, 10])], z[([7, 10])])
              ax.plot(x[([10, 11])], y[([10, 11])], z[([10, 11])])
              ax.plot(x[([11, 12])], y[([11, 12])], z[([11, 12])])
              ax.plot(x[([7, 13])], y[([7, 13])], z[([7, 13])])
              ax.plot(x[([13, 14])], y[([13, 14])], z[([13, 14])])
              ax.plot(x[([14, 15])], y[([14, 15])], z[([14, 15])])
  
              # Create cubic bounding box to simulate equal aspect ratio
              max_range = np.array([x.max() - x.min(), y.max() - y.min(), z.max() - z.min()]).max()
              Xb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5 * (x.max() + x.min())
              Yb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5 * (y.max() + y.min())
              Zb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5 * (z.max() + z.min())
  
              for xb, yb, zb in zip(Xb, Yb, Zb):
                  ax.plot([xb], [yb], [zb], 'w')
  
              plt.axis('equal')
  
          a = anim.FuncAnimation(fig, update, frames=poses.shape[0], repeat=False)
          plt.show()
          
      return
  