How to numerically compute the mass map and density map for a collection of masses?

Question:

Good day to everyone. I was wondering if there is any way to extract a mass map and a mass density map for a scatter plot of mass distributions.

Developing the code for the mass distributions:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.ndimage.filters import gaussian_filter
from numpy.random import rand

# Finds nran number of random points in two dimensions
def randomizer(nran):
    arr = rand(nran, 2)
    return arr

# Calculates a sort of 'density' plot. Using this from a previous StackOverflow Question: https://stackoverflow.com/questions/2369492/generate-a-heatmap-in-matplotlib-using-a-scatter-data-set
def myplot(x, y, s, bins = 1000):
    plot, xedges, yedges = np.histogram2d(x, y, bins = bins)
    plot = gaussian_filter(plot, sigma = s)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    return plot.T, extent

Trying out an example:

arr = randomizer(1000)
plot, extent = myplot(arr[:, 0], arr[:, 1], 20)
fig, ax = plt.subplots(1, 2, figsize = (15, 5))

ax[0].scatter(arr[:, 0], arr[:, 1])
ax[0].set_aspect('equal')
ax[0].set_xlabel('x')
ax[0].set_ylabel('y')
ax[0].set_title('Scatter Plot')

img = ax[1].imshow(plot)
ax[1].set_title('Density Plot?')
ax[1].set_aspect('equal')
ax[1].set_xlabel('x')
ax[1].set_ylabel('y')
plt.colorbar(img)

This yields a scatter plot and what I think kind of represents a density plot (please correct if wrong). Now, suppose that each dot has a mass of 50 kg. Does the "density plot" represent a map of the total mass distribution (if that makes sense?)since the colorbar has a max value much less than 50. Then, using this, how can I compute a mass density for this mass distribution? I would really appreciate if someone could help. Thank you.

Edit: Added the website from where I got the heatmap function.

Asked By: PhysicsProgrammer

||

Answers:

Okay, I think I’ve got the solution. I’ve been meaning to upload this for quite an amount of time. Here it goes:


    # Importing packages
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    from numpy.random import random
    from scipy.stats import binned_statistic_2d
    
    
    # Finds nran number of random points in two dimensions
    def randomizer(nran):
        arr_x = []
        arr_y = []
        for i in range(nran):
            arr_x += [10 * random()] # Since random() only produces floats in (0, 1), I multiply by 10 (for illustrative purposes)
            arr_y += [10 *random()] # Since random() only produces floats in (0, 1), I multiply by 10 (for illustrative purposes)
        return arr_x, arr_y
    
    # Computing weight array
    def weights_array(weight, length):
        weights = np.array([weight] * length)
        return weights
    
    # Computes a weighted histogram and divides it by the total grid area to get the density 
    def histogramizer(x_array, y_array, weights, num_pixels, Dimension):
        Range = [0, Dimension] # Assumes the weights are distributed in a square area
        grid, _, _, _ = binned_statistic_2d(x_array, y_array, weights, 'sum', bins=num_pixels, range=[Range,Range])
        area = int(np.max(x_array)) * int(np.max(y_array))
        density = grid/area
        return density

Then, actually implementing this, one finds:

arr_x, arr_y = randomizer(1000000)
weights = []
for i in range(len(arr_x)):
    weights += [50]
density = histogramizer(arr_x, arr_y, weights, [400,400], np.max(arr_x))
fig, ax = plt.subplots(figsize = (15, 5))
plt.imshow(density, extent = [0, int(np.max(arr_x)), 0, int(np.max(arr_x))]);
plt.colorbar(label = '$kg m^-2$');

The result I got for this was the following plot (I know it’s generally not recommended to add a photo, but I wanted to add it for sake of showing my code’s output):

Output of code showing mass density with units of $$kg cdot m^{-2}$$

Answered By: PhysicsProgrammer