Reputation: 1284
Basically, I'd like to make something like the following (triangles not squares as is typically used with plt.matshow).
One could start with four 2D arrays, each representing the values for the colours of a set of triangles: right, left, bottom, top:
import numpy as np
right=np.random.randn(8, 8)
left=np.random.randn(8, 8)
bottom=np.random.randn(8, 8)
top=np.random.randn(8, 8)
But I have no idea about the plotting...
Upvotes: 3
Views: 1063
Reputation: 1
I used ImportanceOfBeingErnest's code to plot the Q-table for a reinforcement learning project- I wanted to understand it so I went through and made it a bit clearer. Just replace the data (up, down, left, right) with your own.
def showQVals(self):
fig, ax = plt.subplots()
rows = self.level.NUM_ROWS
cols = self.level.NUM_COLUMNS
up = self.q[:,Action.UP].reshape(rows, cols)
down = self.q[:,Action.DOWN].reshape(rows, cols)
right = self.q[:,Action.RIGHT].reshape(rows, cols)
left = self.q[:,Action.LEFT].reshape(rows, cols)
vertDims = np.array([[0,0],[0,1],[.5,.5],[1,0],[1,1]])
UP = [1,2,4]
DOWN = [0,2,3]
RIGHT = [2,3,4]
LEFT = [0,1,2]
triDims = np.array([DOWN, UP, RIGHT, LEFT])
verts = np.zeros((rows*cols*5,2))
tris = np.zeros((rows*cols*4,3))
for row in range(rows): #i
for col in range(cols): #j
cell = row*cols+col
#assign slices to the newly constructed verts and tris
verts[cell*5:(cell+1)*5,:] = np.c_[vertDims[:,0]+col, vertDims[:,1]+row]
tris[cell*4:(cell+1)*4,:] = triDims + cell*5
C = np.c_[ up.flatten(), down.flatten(),
right.flatten(), left.flatten() ].flatten()
ax.invert_yaxis()
ax.set_title('Q Values')
triplot = ax.triplot(verts[:,0], verts[:,1], tris)
tripcolor = ax.tripcolor(verts[:,0], verts[:,1], tris, facecolors=C)
fig.colorbar(tripcolor)
plt.show()
q table figure based off of grid map
Upvotes: -1
Reputation: 339170
You may indeed use tripcolor
to plot a set of triangles. In the code below the function quatromatrix
takes 4 2D arrays of values to colormap as input, creates the triangles and rearanges the colors to fit to the respective positions. It is thus very similar to plotting 4 imshow plots.
import matplotlib.pyplot as plt
import numpy as np
def quatromatrix(left, bottom, right, top, ax=None, triplotkw={},tripcolorkw={}):
if not ax: ax=plt.gca()
n = left.shape[0]; m=left.shape[1]
a = np.array([[0,0],[0,1],[.5,.5],[1,0],[1,1]])
tr = np.array([[0,1,2], [0,2,3],[2,3,4],[1,2,4]])
A = np.zeros((n*m*5,2))
Tr = np.zeros((n*m*4,3))
for i in range(n):
for j in range(m):
k = i*m+j
A[k*5:(k+1)*5,:] = np.c_[a[:,0]+j, a[:,1]+i]
Tr[k*4:(k+1)*4,:] = tr + k*5
C = np.c_[ left.flatten(), bottom.flatten(),
right.flatten(), top.flatten() ].flatten()
triplot = ax.triplot(A[:,0], A[:,1], Tr, **triplotkw)
tripcolor = ax.tripcolor(A[:,0], A[:,1], Tr, facecolors=C, **tripcolorkw)
return tripcolor
right=np.random.randn(8, 8)
left=np.random.randn(8, 8)
bottom=np.random.randn(8, 8)
top=np.random.randn(8, 8)
fig, ax=plt.subplots()
quatromatrix(left, bottom, right, top, ax=ax,
triplotkw={"color":"k", "lw":1},
tripcolorkw={"cmap": "plasma"})
ax.margins(0)
ax.set_aspect("equal")
Upvotes: 3
Reputation: 1156
See the example matplotlib.pyplot.tripcolor(*args, **kwargs)
in the matplotlib documentation here.
Here is a simplyfied version of want you need:
import matplotlib.pyplot as plt
import numpy as np
xy = np.asarray([
[-0.01, 0.872], [-0.080, 0.883], [-0.069, 0.888], [-0.054, 0.890]])
x = xy[:, 0]*180/3.14159
y = xy[:, 1]*180/3.14159
triangles = np.asarray([[3, 2, 0] , [3, 1, 2], [ 0, 2, 1] ,
[0, 1, 2]])
xmid = x[triangles].mean(axis=1)
ymid = y[triangles].mean(axis=1)
x0 = -5
y0 = 52
zfaces = np.exp(-0.01*((xmid - x0)*(xmid - x0) +
(ymid - y0)*(ymid - y0)))
plt.figure()
plt.gca().set_aspect('equal')
plt.tripcolor(x, y, triangles, facecolors=zfaces, edgecolors='k')
plt.colorbar()
plt.title('tripcolor of user-specified triangulation')
plt.xlabel('Longitude (degrees)')
plt.ylabel('Latitude (degrees)')
plt.show()
You should get the following picture:
Upvotes: 0