Combining properties of pcolormesh and imshow

Viewed 35

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?

2 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

@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!

Related