Search code examples
matplotlibseaborncoordinatesheatmapeuler-angles

How to plot a heatmap of coordinates on a mollweide projection


I have a set of lattitude and longitude coordinates (i.e. a list of lists: [[20,24],[100,-3],...]) that I would like to plot has a heatmap (not just a scatter) on a mollweide projection. Essentially, what I want is a seaborn hist2d plot but as a mollweide. For a reference of what I mean, please see the uploaded picture. Does anyone know how to do this? Mollweide projection of coordinates


Solution

  • I created some random data and showed the way to generate the histogram plot. I hope this is something you are looking for.

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib as mpl
    
    # create some random data for histogram
    base = [[-20, 30], [100, -20]]
    data = []
    for _ in range(10000):
        data.append((
            base[0][0] + np.random.normal(0, 20),
            base[0][1] + np.random.normal(0, 10)
        ))
        data.append((
            base[1][0] + np.random.normal(0, 20),
            base[1][1] + np.random.normal(0, 10)
        ))
    data = np.array(data) / 180 * np.pi  # shape (n, 2)
    
    # create bin edges
    bin_number = 40
    lon_edges = np.linspace(-np.pi, np.pi, bin_number + 1)
    lat_edges = np.linspace(-np.pi/2., np.pi/2., bin_number + 1)
    
    # calculate 2D histogram, the shape of hist is (bin_number, bin_number)
    hist, lon_edges, lat_edges = np.histogram2d(
        *data.T, bins=[lon_edges, lat_edges], density=True
    )
    
    # generate the plot
    cmap = plt.cm.Greens
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='mollweide')
    
    ax.pcolor(
        lon_edges[:-1], lat_edges[:-1],
        hist.T,  # transpose from (row, column) to (x, y)
        cmap=cmap, shading='auto',
        vmin=0, vmax=1
    )
    
    # hide the tick labels
    ax.set_xticks([])
    ax.set_yticks([])
    
    # add the colorbar
    cbar = plt.colorbar(
            plt.cm.ScalarMappable(
                norm=mpl.colors.Normalize(0, 1), cmap=cmap
            )
        )
    cbar.set_label("Density Distribution")
    
    plt.show()
    

    I get the following figure.

    enter image description here