deVacouleurs.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """Compares the matter distribution of the merger to the de Vacouleurs' law"""
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. from scipy.stats import linregress
  5. from analysis import utils
  6. #https://stackoverflow.com/questions/39418380/histogram-with-equal-number-of-points-in-each-bin
  7. def equalNHistogramBins(x, nbin):
  8. """Calculates the bins necessary for a histogram
  9. with equal number of points in each bin
  10. """
  11. return np.interp(np.linspace(0, len(x), nbin + 1), np.arange(len(x)), np.sort(x))
  12. def plotRadialMagnitude(data, ax):
  13. """Plots the magnitude (log(areal density)) as a function of radius"""
  14. xs, ys = [], []
  15. # Project onto all three planes calculate the areal density and plot the graph
  16. for dim, style, label in zip([[1,2],[0,2],[0,1]], ['o','s','x'], ['Onto y-z plane', 'Onto x-z plane', 'Onto x-y plane']):
  17. # Measure radial distance with respect to COM
  18. COM = np.sum(data['r'] * data['mass'][:,np.newaxis], axis=0) / np.sum(data['mass'])
  19. r = np.linalg.norm((data['r'] - COM)[:,dim], axis=-1)
  20. hist, bin_edges = np.histogram(r[data['types']=='disk'],
  21. histedges_equalN(r[data['types']=='disk'], 30), density=True)
  22. bin_edges = (bin_edges[:-1] + bin_edges[1:])/2
  23. M = np.log(hist) #Magnitude
  24. if style == 'x':
  25. plt.scatter((bin_edges**(1/4)), M, marker=style,
  26. c='black', label=label)
  27. else:
  28. plt.scatter((bin_edges**(1/4)), M, marker=style,
  29. facecolors='none', edgecolors='black', label=label)
  30. # Omit points on both ends for the fit, where the law does not hold
  31. xs.extend((bin_edges**(1/4))[5:-2])
  32. ys.extend(M[5:-2])
  33. utils.setSize(ax, x=(.5, 1.4), y=(-3.5, 1))
  34. utils.setAxes(ax, x=r'$r^{1/4}$', y=r'$M$', xcoords=(.9,-0.08), ycoords=(-0.08,.9))
  35. utils.stylizePlot([ax])
  36. #Fit a line to the data
  37. slope, intercept, r_value, _, _ = linregress(xs, ys)
  38. x = np.linspace(.55, 1.35, 10)
  39. fit = np.poly1d((slope, intercept))(x)
  40. plt.plot(x, fit, linewidth=.5, label='Global fit', c='black')
  41. plt.text(.6, -3, r'$R^2 = {:.2f}$'.format(r_value**2), fontsize=14)
  42. plt.legend()
  43. data = utils.loadData('hyperbolic_halo', 30000)
  44. f, ax = plt.subplots(1, 1)
  45. plotRadialMagnitude(data, None, ax)