Note
Go to the end to download the full example code.
The Kerr shadow: a rotating black hole’s asymmetric silhouette#
A rotating black hole’s shadow is not a perfect circle like Schwarzschild’s: frame dragging shifts and flattens it along the direction of rotation, and the accretion disk’s approaching side is Doppler-boosted bright while the receding side dims – exactly the asymmetric brightness pattern seen in the 2019 Event Horizon Telescope image of M87*. This example ray-traces the full (non-equatorial) Kerr null geodesic equations – using Carter’s separated equations of motion in Mino time – to render the shadow of a black hole of mass \(M\) and spin parameter \(a\) at increasing spin, and shades a thin, circularly orbiting equatorial accretion disk by its combined gravitational and Doppler redshift
where \(b = L_{\text{ph}}/E_{\text{ph}}\) is the received photon’s impact parameter, \(\Omega(r)\) is the disk’s Keplerian angular velocity, and \(u^t(r)\) is the emitting gas’s time-dilation factor; \(g>1\) (blueshifted) marks the approaching side and \(g<1\) (redshifted) the receding side. Rendered brightness is further boosted by \(g^3\), the relativistic Doppler-beaming factor for a locally isotropic emitter.
import matplotlib.pyplot as plt
from physicskit.relativity.visualizers.shadow_render import plot_black_hole_shadow, render_black_hole_image
The shadow shrinks and shifts as spin increases#

A redshift-shaded accretion disk (near-extremal spin, oblique view)#
result = render_black_hole_image(M=1.0, a=0.9, ny=250, nx=250, inclination=1.35, screen_half_width=18.0)
fig, axes = plt.subplots(1, 2, figsize=(13, 6))
plot_black_hole_shadow(result, ax=axes[0], redshift=False)
axes[0].set_title("Colored by radius only")
plot_black_hole_shadow(result, ax=axes[1], redshift=True)
axes[1].set_title("Doppler-shaded: approaching side brighter")
plt.tight_layout()
plt.show()

Total running time of the script: (0 minutes 12.992 seconds)