Search code examples
pythonmatplotlibcolors

Plot Angular Grid with filled cells based on Color Map


I would like to do a transformation between two coordinate systems and also like to show filled cells accordingly as shown below:-

enter image description here

I have been able to create the below filled grid the way I want, but I am not quite sure how to draw the angular transformed grid.

import numpy as np
import matplotlib.pyplot as plt

z_min = 10
z_max = 100
n_zcells = 10
z_array = np.linspace(z_min, z_max, n_zcells)

u_min = -9.5
u_max = 9.5
n_ucells = 15
u_array = np.linspace(u_min, u_max, n_ucells)

[u_grid, z_grid] = np.meshgrid(u_array, z_array)

# %% Represent Polar Grid in Cartesian Coordinates

f = 5   # Focal length in pixels
B = 10  # Baseline in cm

# u = fX/Z; Equation for Camera to Pixel Coordinates

x_grid = u_grid*z_grid/f

# %% Desired Grid Points

plt.figure()
plt.subplot(2,1,1)
plt.scatter(x_grid, z_grid)
plt.xlabel('Lateral Distance (cm)')
plt.ylabel('Depth (cm)')
plt.subplot(2,1,2)
plt.scatter(u_grid, z_grid) 
plt.xlabel('Pixel Column ')
plt.ylabel('Depth (cm)')
plt.show()

# %%  Filled Grid Cell Colours

filled_colours = np.random.rand(n_zcells-1,n_ucells-1) # No. of cells will be 1 less than no. of grid points
plt.imshow(filled_colours, cmap=plt.get_cmap('gray'), origin='lower')

Is there some proper way to fill the grid obtained in cartesian coordinates which is angular, with the colors obtained for the rectangular grid? I tried looking at plt.fill() and plt.contour() but couldn't really get it right. Any help is appreciated.


Solution

  • I have a working solution based on the patch approach suggested by @Thijs in the comments, where I go block by block for each polygon and fill in the colors as obtained in the output of the colormap.

    ####### Continuing from the code snippet posted in the question #######
    from matplotlib.patches import Polygon
    
    # %%  Filled Grid Cell Colours
    filled_colours = np.random.rand(n_zcells-1,n_ucells-1) # No. of cells will be 1 less than no. of grid points 
    
    fig3, (ax1, ax2) = plt.subplots(ncols=2)
    ax1.imshow(filled_colours, cmap=plt.get_cmap('gray'), origin='lower')
    ax1.set_title('Occupancy Grid in Polar Coordinates', fontweight="bold")
    ax1.set_xlabel('Pixel Column u (px)')
    ax1.set_ylabel('Depth z (cm)')
    ax1.set_anchor('C')
    
    ax2.plot(x_grid, z_grid, color = "k", linewidth = 0.5)
    cmap = plt.cm.get_cmap('gray')
    colors = cmap(filled_colours/np.max(filled_colours))
    
    # Block by Block Polygon Coloured Patch Added 
    for i in range(n_zcells-1):
        for j in range(n_ucells-1):
            v1 = [x_grid[i,j], z_grid[i,j]]
            v2 = [x_grid[i+1,j], z_grid[i+1,j]]
            v3 = [x_grid[i+1,j+1], z_grid[i+1,j+1]]
            v4 = [x_grid[i,j+1], z_grid[i,j+1]]
            color_cell = colors[i,j,:]
            # v1-v4 are the Polygon vertices in cartesian coordinates
            ax2.add_patch(Polygon([v1, v2, v3, v4], color = color_cell))        
    
    ax2.set_title('Occupancy Grid in Cartesian Coordinates', fontweight="bold")
    ax2.set_xlabel('Lateral Distance x(cm)')
    ax2.set_ylabel('Depth z (cm)')
    ax2.set_anchor('C')
    
      
    # creating ScalarMappable
    sm = plt.cm.ScalarMappable(cmap=cmap,)
    sm.set_array([])
    
    plt.colorbar(sm, ax=ax2)
    plt.show()
    

    The output is as follows:- enter image description here