Reputation: 1019
I'm working with Matplotlib and Python in the plotting of 2D skeletons made of joints connected by lines (that data comes from a text file of coordinates, representing the (x,y) joints), side by side with a distance matrix of each joint to all the others, for each skeleton plotted, generated by some calculations with the same text file data.
By now, I've plotted the skeletons, connected to a key press event, what means that by each text file read, a number of skeletons is plotted, generating a movement, and the movement is perceptible since the user must press the right arrow key to plot the sequence of skeletons, one by one, and the movement is visible ever since.
Also, I've built the matrices, and each matrix is plotted in a blue scale with a color bar aside, after some calculation in the code. I've tested the plotting of each matrix, and it's working fine. Notice that if I have 43 skeletons in a text file, there must be 43 matrices, one for each skeleton.
The problem is: I've used thescatter method to plot the skeletons, with one figure and one axis only. I must plot each matrix aside the skeleton, and I'm using imshow to plot the matrices from an array into a graph, in the format of an image, like an image. But I can't figure out how to organize prorperly the axis and plot the matrix aside de skeleton, without having to add another axis, like fig, (ax1,ax) = plt.subplots(ncols=2), for example. Since I'm a beginner in Matplotlib, I'm a bit confused about how to plot the matrix side by side the skeletons, without having to rebuilt the method for plotting the skeletons.
The code:
from matplotlib import gridspec
import matplotlib.pyplot as plt
import numpy as np
movement = np.loadtxt("file01.txt")
bone_list = [[1, 3], [2, 3], [3, 4], [4, 7], [5, 7], [6, 7], [1, 8], [2, 9],
[8, 10], [9, 11], [10, 12], [11, 13], [5, 14], [6, 15], [14, 16], [15, 17],
[16, 18], [17, 19], [3, 20]]
bone_list = np.array(bone_list) - 1
number_of_postures = int(len(movement)/20)
list_for_matrix = []
for i in range(number_of_postures):
list_for_matrix.append(movement[(i*20):((i+1)*20),:3])
matrixCoord = np.array(list_for_matrix)
matrixDistance= np.zeros((number_of_postures,20,20))
for k in range(number_of_postures):
for i in range(len(matrixDistance[0])):
for j in range(len(matrixDistance[0])):
matrixDistance[k,i,j] = np.linalg.norm(matrixCoord[k,i,:] -
matrixCoord[k,j,:])
fig, ax = plt.subplots()
i = 1 #this variable is for plotting from the second skeleton on with the function call.
def press(event):
global i
if event.key == 'right':
fig.canvas.draw_idle()
plt.cla()
plt.xlim(100, 190)
plt.ylim(-250, 0)
skeleton = movement[i*20:(i+1)*20]
x = skeleton[:, 0]
y = -skeleton[:, 1]
sc = ax.scatter(x, y, s=40)
for bone in bone_list:
ax.plot([x[bone[0]], x[bone[1]]], [y[bone[0]], y[bone[1]]], 'r')
plt.subplots_adjust(left=0.12, bottom=0.11, right=0.49, top=0.93,wspace=0.20, hspace=0.20)
if i < number_of_postures:
i+=1
else:
return
#plot of the first skeleton, outside the function call.
plt.xlim(100, 190)
plt.ylim(-250, 0)
skeleton = movement[0*20:(0+1)*20]
x = skeleton[:, 0]
y = -skeleton[:, 1]
sc = ax.scatter(x, y, s=40)
for bone in bone_list
ax.plot([x[bone[0]], x[bone[1]]], [y[bone[0]], y[bone[1]]], 'r')
plt.subplots_adjust(left=0.12, bottom=0.11, right=0.49,top=0.93,wspace=0.20, hspace=0.20)
fig.canvas.mpl_connect("key_press_event", press)
plt.show()
#that's the plotting for the matrices, outside the plt.show(), since it's not working properly.
'''
img = matrixDistance[i]
imgplot = plt.imshow(img)
plt.title('Distance Matrix')
imgplot.set_cmap('PuBu')
plt.colorbar()
'''
Below, there are two pictures, the result generated by the code, and an idea of what I need to achieve yet.
Result generated by the code:
What I need to achieve yet:
Upvotes: 0
Views: 539
Reputation: 3147
Most commands affecting subplots replace any axis existing in the same area. You've created a single axes for the figure with the line
fig, ax = plt.subplots()
Subsequent calls to subplots
or subplot
will remove this axis and create a new one. You need to setup both axes at the same time. You can execute
fig, (ax1, ax2) = figure(ncol=2)
Then use
sca(ax1)
before your current code. That will make ax1
the axis matplotlib draws on. After the current code and before the code to draw matrices use the command again to set ax2 (i.e. sca(ax2)
).
Upvotes: 1