Search code examples
pythonmatplotlibjupyter-notebookastronomy

Data point colours changing radially from a pre specified point


I am wanting to set the colours of certain data points to be centred around a certain point, e.g., [1,2] on my graph, so the further away the data points are from a central point they begin to change colour. So there is some radius from this point where data points within are one colour, and so on.

I would specifically like to create a heat map with the follow hex colour codes:

FF0088, FF0099, FF00AA and 660088, 660099, 6600AA

I would also like to have the distinct colour change either side of a demarcation line.

import numpy as np
import matplotlib.pyplot as plt

data_dC = [
        [1.29940,-0.06908,0.85295,-0.32388,0.51436,0.00408,-0.83824,-0.11374,0.04466],
        [0.93471,0.10030,1.25981,-0.11888,1.35810,-0.12869,-1.47697,0.02932,0.07098],
        [0.57901,0.25031,1.77954,-0.34448,0.94303,-0.20675,-1.28751,0.23731,0.01300],
        [0.51240,0.53625,3.43752,-0.21142,0.83936,0.19316,-1.05078,0.29039,0.24586],
        [0.23750,0.81001,6.45671,-0.21533,0.50952,-0.09047,-0.72484,0.62434,0.18567],
        [0.68737,0.38333,2.41730,-0.32624,0.87260,-0.00159,-1.19884,0.16281,0.22052],
        [0.61870,0.16834,1.47348,-0.18783,0.55844,0.33093,-0.74627,0.20852,-0.04018],
        [2.05987,-0.36247,0.43404,-0.21760,0.95765,0.04392,-1.17525,-0.31384,-0.04863],
        [0.32613,0.18240,1.52197,-0.30043,1.00514,-0.00491,-1.30558,0.48662,-0.30421],
        [0.90927,-0.16005,0.69175,-0.26315,1.19294,-0.02365,-1.45609,0.04131,-0.20136],

def log_OIII_OII_OI(log_OI_Ha, eps=0):
    return ((-1.701)*(log_OI_Ha))-2.163

OI2 = np.linspace(-2.50000, 0.00000)

data_dC = np.array(data_dC)

log_OIHa_dC    = data_dC[:, 6]
log_OIIIOII_dC = data_dC[:, 7]

base_point = (-1.4, -0.8)

def boundary_x(x):
    return ((-1.701)*(x))-2.163

def myDistance(log_OIHa_dC, log_OIIIOII_dC, base):
return np.sqrt((log_OIHa_dC - base[0])**2 + (log_OIIIOII_dC - base[1])**2)

dist = myDistance(log_OIHa_dC, log_OIIIOII_dC, base_point)

fig, ax = plt.subplots()
ax.plot(OI2, log_OIII_OII_OI(OI2), '-k')
ax.set_yticks([-1.5,-1.0,-0.5,0.0,0.5])
ax.set_xlim(-2.5, 0.0)
ax.set_ylim(-1.5, 1.0)

ax.plot(base_point[0], base_point[1], 'ko')
ax.scatter(log_OIHa_dC[log_OIHa_dC >= boundary_x(x)], log_OIIIOII_dC[log_OIHa_dC >=       boundary_x(x)], c=dist[log_OIHa_dC >= boundary_x(x)], cmap=plt.cm.Blues)
ax.scatter(log_OIHa_dC[log_OIHa_dC < boundary_x(x)], log_OIIIOII_dC[log_OIHa_dC < boundary_x(x)], c=dist[log_OIHa_dC < boundary_x(x)], cmap=plt.cm.Reds)

So essentially to the upper right of this demarcation line I would like the hex colours 660088, 660099, 6600AA and to the lower left of it I would like FF0088, FF0099, FF00AA.

The point to the lower left of the demarcation line is [-1.4,-0.8] and the point to the upper right of the demarcation line is [-0.9,0.2].


Solution

  • You need to use ax.scatter and feed it colors based on the distance from your point. You can also use numpy's fancy indexing to select things based on criteria (like your demarcation line).

    You don't include any example images of what you'd like to see, so here's a basic example of these concepts put together:

    import numpy as np
    import matplotlib.pyplot as plt
    np.random.seed(0)
    %matplotlib inline
    
    def myBoundary(x, y0=0, slope=1):
        return y0 + x * slope
    
    def myDistance(x, y, base_x, base_y):
        return np.sqrt((x - base_x)**2 + (y - base_y)**2)
    
    x = np.random.normal(size=137)
    y = np.random.normal(size=137)
    
    y_boundary = myBoundary(x)
    
    base_x, base_y = (-1.4, -0.8)
    
    dist = myDistance(x, y, base_x, base_y)
    
    fig, ax = plt.subplots()
    ax.scatter(x[y >= y_boundary], y[y >= y_boundary], c=dist[y >= y_boundary], cmap=plt.cm.Blues_r)
    ax.scatter(x[y < y_boundary], y[y < y_boundary], c=dist[y < y_boundary], cmap=plt.cm.Reds_r)
    ax.plot(x, y_boundary, linestyle='-', linewidth=2, marker=None, color='k', alpha=0.65) 
    ax.plot(base_x, base_y, 'g*', alpha=0.65, markersize=10)
    

    And that dumps out:

    fancy scatter plot