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
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:
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
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")