Combining properties of pcolormesh and imshow

Question:

An advantage of plt.pcolormesh over plt.imshow is the possibility to have unequal axis spacing.

On the other hand, plt.imshow‘s advantage over plt.pcolormesh is that it can display RGB-triplets.

Now, the predicament I am in is that I need to plot RGB-triplets with uneven axis spacing….

Below is a MWE:

import numpy as np
import matplotlib.pyplot as plt
from colorsys import  hsv_to_rgb

square_x_axis = np.linspace(0,1,100)**2
cube_y_axis = np.linspace(0,1,200)**3

X,Y = np.meshgrid(cube_y_axis,square_x_axis); print(f'meshgrid has shape: {X.shape}')

rgb_array = np.zeros((square_x_axis.size, cube_y_axis.size,3)); print(f'rgb_array has shape: {rgb_array.shape}')
""" Now we populate the rgb array (initially in hsv color space for clarity)"""
for i,row in enumerate(rgb_array):
    for j,col in enumerate(row):
        rgb_array[i,j,:] = np.array(hsv_to_rgb(0,square_x_axis[i],cube_y_axis[j]))

fig = plt.figure(figsize=(15,10))
imshow_ax = plt.subplot(1,2,1)
imshow_ax.imshow(rgb_array, aspect='auto', extent=[0,1,0,1])
pcolor_R_ax = plt.subplot(3,2,2)
pcolor_R_ax.pcolormesh(X,Y,rgb_array[:,:,0], cmap='Reds')
pcolor_G_ax = plt.subplot(3,2,4)
pcolor_G_ax.pcolormesh(X,Y,rgb_array[:,:,1], cmap='Greens')
pcolor_B_ax = plt.subplot(3,2,6)
pcolor_B_ax.pcolormesh(X,Y,rgb_array[:,:,2], cmap='Blues')

Which produces the following figure:

enter image description here

The problem becomes immediately obvious: imshow (on the left) is capable of representing the 3D array, but its axis are scaled wrong, leading to a distorted representation. pcolormesh (on the right), on the other hand, can not represent the 3D array (hence why I plot all three channels separately), but is capable of applying the axis correctly, leading to no distortion.

How can I combine these properties?

Asked By: Douglas James Bock

||

Answers:

I found another answer here that seems to work on your example, with a small tweak for some new pcolorbesh behaviour (the shading='auto' bit). Try this plot on your data:

fig = plt.figure(figsize=(15,10))
placeholder = rgb_array[..., 0]
colors = rgb_array.reshape(-1, 3)
mesh = plt.pcolormesh(X, Y, placeholder, facecolors=colors, shading='auto')
mesh.set_array(None)

It produces:

Output of the code

Answered By: kwinkunks

@kwinkunks answer is the method that solved my problem:
The original data, using imshow, looked like this, where both the x- and y-axis of the data plot and the colorbar are wrong. Of all 4 axes, only the data y-axis is linear, the 3 other axes are non-linear, and so using imshows‘s extent option is no good:

enter image description here

Now… taking @kwinkunks answer directly produced the following plot:

enter image description here

…where the axes tickmarks are now as they should be! Amazing!

Answered By: Douglas James Bock
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.