简体   繁体   中英

Circular interpolated heat map plot using python

I have data that represents values at interior points within a circle. I would like to create a heat map similar tohttp://matplotlib.org/examples/pylab_examples/image_interp.html . Anybody familiar with a method for doing this with a circle?

You can do this by using a polar projection on your axis. Note, that this will not work with imshow as per the example you gave. (See: http://en.it-usenet.org/thread/15998/715/ ) However you can still do interpolation and then plot a heat map. Below is a simple example:

from pylab import *
import numpy as np
from scipy.interpolate import griddata

#create 5000 Random points distributed within the circle radius 100
max_r = 100
max_theta = 2.0 * np.pi
number_points = 5000
points = np.random.rand(number_points,2)*[max_r,max_theta]

#Some function to generate values for these points, 
#this could be values = np.random.rand(number_points)
values = points[:,0] * np.sin(points[:,1])* np.cos(points[:,1])

#now we create a grid of values, interpolated from our random sample above
theta = np.linspace(0.0, max_theta, 100)
r = np.linspace(0, max_r, 200)
grid_r, grid_theta = np.meshgrid(r, theta)
data = griddata(points, values, (grid_r, grid_theta), method='cubic',fill_value=0)

#Create a polar projection
ax1 = plt.subplot(projection="polar")
ax1.pcolormesh(theta,r,data.T)
plt.show()

Note that I have used a fill_value of 0, so any values in the grid that fall outside the convex shape of the random data will have the value of 0.

Interpolated Polar Heatmap If you wish to do the same you will need to convert your data into polar coordinates before doing the same, (assuming your readings are in Cartesian coordinates). To do that you can use:

def convert_to_polar(x, y):
    theta = np.arctan2(y, x)
    r = np.sqrt(x**2 + y**2)
    return theta, r 

You may find the answers to these questions helpful too: image information along a polar coordinate system Adding a colorbar to a pcolormesh with polar projection

The first of those in particular has a really detailed answer.

I appreciate that this is an old question, but as I made use of the answer by Weir_Doe and developed it in a slightly different way, I thought I'd contribute my method in the hope that it helps someone else.

I was trying to do something similar, and collected results for r and theta in a systematic fashion, as such I ended up with a grid. Once you have a grid you can use a zoom to get a higher definition image.

from pylab import *
import numpy as np
from scipy.ndimage import zoom
import pandas as pd

max_r = 100
max_theta = 2.5 * np.pi
number_points = 5

#Generate a grid 100 x 100 r x theta
r = np.arange(0, max_r,max_theta/number_points)
theta = np.arange(0,max_theta,max_theta/number_points)
grid_r, grid_theta = np.meshgrid(r, theta)

#Generate random numbers for each grid point
values = (np.sin(grid_r)+np.cos(grid_theta)).flatten()


#I always find it easier to put it in a dataframe
df = pd.DataFrame(grid_r.flatten()).rename(columns={0:'r'})
df['theta'] = grid_theta.flatten()
df['values'] = values
df = df.pivot(index='theta', columns='r')
#printing the dataframe at this point is very helpful conceptually

#Create a polar projection
ax1 = plt.subplot(projection="polar")
ax1.pcolormesh(df.index,r,df.values.T)
plt.show()

#Zoom in to the grid, this interpolates the results onto a finer grid
#Here I chose a 10x finer grid, this is more efficient than to interpolate onto specified points
zoom_factor=10

zoomed_df = zoom(df, zoom_factor)
zoomed_index = zoom(theta, zoom_factor)
zoomed_columns = zoom(r, zoom_factor)
high_def_grid = pd.DataFrame(zoomed_df, index=zoomed_index, columns=zoomed_columns)


#Create a polar projection
ax1 = plt.subplot(projection="polar")
ax1.pcolormesh(high_def_grid.index,high_def_grid.columns,high_def_grid.values.T)
plt.show()

This results in 2 images, the pre-interpolate image:

Uninterpolate polar plot

And the post-interpolation plot:

Interpolated polar plot

like I say, this only works if the data is collected in a systematic way, but for scientific purposes, this will be the case.

Additionally, using a pandas dataframe is not a necessary step, but I find it conceptually much simpler when doing it this way.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM