How to add a 2D matrix or color wheel to matplotlib?

I analyze the magnetization of a sample. Having received the gradient and its direction, I built them as HSV (the direction from -Ο€ to Ο€ was mapped to Hue from 0 to 1, and Value to the normalized gradient), converted to RGB by img_rgb = mpl.colors.hsv_to_rgb(img_hsv) .

I managed to add the HSV color panel using vmin and vmax, but this does not show the magnitude of the gradient:

 plt.imshow(img_rgb, cmap='hsv', vmin=-180, vmax=180, extent=(0, 100, 0,100)) plt.xlabel('ΞΌm') plt.ylabel('ΞΌm') plt.colorbar() 

My current plot :
enter image description here

Ideally, I would like to add a color wheel that encodes both direction and magnitude (perhaps something like a polar story?). If this is not possible, add a 2D graph that extends the current color bar to include the x-axis gradient value.

Substrates are obviously possible, but they seem like bugs. Is there a better way?

+3
source share
1 answer

First of all, if you have two different parameters that you want to visualize at the same time, you can do this by assigning them two different channels (for example, red and green). This can be done by normalizing two two-disk arrays and bringing them to imshow in the same way as this answer .

If you are happy with the square 2-digit color palette, you can get this color meshgrid in the same way by creating a meshgrid , which then folds back and feeds to imshow :

 from matplotlib import pyplot as plt import numpy as np ##generating some data x,y = np.meshgrid( np.linspace(0,1,100), np.linspace(0,1,100), ) directions = (np.sin(2*np.pi*x)*np.cos(2*np.pi*y)+1)*np.pi magnitude = np.exp(-(x*x+y*y)) ##normalize data: def normalize(M): return (M-np.min(M))/(np.max(M)-np.min(M)) d_norm = normalize(directions) m_norm = normalize(magnitude) fig,(plot_ax, bar_ax) = plt.subplots(nrows=1,ncols=2,figsize=(8,4)) plot_ax.imshow( np.dstack((d_norm,m_norm, np.zeros_like(directions))), aspect = 'auto', extent = (0,100,0,100), ) bar_ax.imshow( np.dstack((x, y, np.zeros_like(x))), extent = ( np.min(directions),np.max(directions), np.min(magnitude),np.max(magnitude), ), aspect = 'auto', origin = 'lower', ) bar_ax.set_xlabel('direction') bar_ax.set_ylabel('magnitude') plt.show() 

The result is as follows:

square shape 2d colorbar

In principle, the same should be done with polar Axes , but according to the comment on this github ticket , imshow does not support polar axes, and I could not make imshow fill the entire disk.

EDIT

Thanks to ImportanceOfBeingErnest and his answer to another question (the color keyword did this), now there is a 2-digit color sign on the polar axis using pcolormesh . There were a few warnings, the most noteworthy, the colors dimension should be less than the meshgrid direction in theta , otherwise the color palette has a spiral shape:

 fig= plt.figure(figsize=(8,4)) plot_ax = fig.add_subplot(121) bar_ax = fig.add_subplot(122, projection = 'polar') plot_ax.imshow( np.dstack((d_norm,m_norm, np.zeros_like(directions))), aspect = 'auto', extent = (0,100,0,100), ) theta, R = np.meshgrid( np.linspace(0,2*np.pi,100), np.linspace(0,1,100), ) t,r = np.meshgrid( np.linspace(0,1,99), np.linspace(0,1,100), ) image = np.dstack((t, r, np.zeros_like(r))) color = image.reshape((image.shape[0]*image.shape[1],image.shape[2])) bar_ax.pcolormesh( theta,R, np.zeros_like(R), color = color, ) bar_ax.set_xticks(np.linspace(0,2*np.pi,5)[:-1]) bar_ax.set_xticklabels( ['{:.2}'.format(i) for i in np.linspace(np.min(directions),np.max(directions),5)[:-1]] ) bar_ax.set_yticks(np.linspace(0,1,5)) bar_ax.set_yticklabels( ['{:.2}'.format(i) for i in np.linspace(np.min(magnitude),np.max(magnitude),5)] ) bar_ax.grid('off') plt.show() 

This gives the following figure:

working round 2d colormap

+2
source

Source: https://habr.com/ru/post/1263637/


All Articles