{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Shaded & power normalized rendering\n\nThe Mandelbrot set rendering can be improved by using a normalized recount\nassociated with a power normalized colormap (gamma=0.3). Rendering can be\nfurther enhanced thanks to shading.\n\nThe ``maxiter`` gives the precision of the computation. ``maxiter=200`` should\ntake a few seconds on most modern laptops.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\n\ndef mandelbrot_set(xmin, xmax, ymin, ymax, xn, yn, maxiter, horizon=2.0):\n X = np.linspace(xmin, xmax, xn).astype(np.float32)\n Y = np.linspace(ymin, ymax, yn).astype(np.float32)\n C = X + Y[:, None] * 1j\n N = np.zeros_like(C, dtype=int)\n Z = np.zeros_like(C)\n for n in range(maxiter):\n I = abs(Z) < horizon\n N[I] = n\n Z[I] = Z[I]**2 + C[I]\n N[N == maxiter-1] = 0\n return Z, N\n\n\nif __name__ == '__main__':\n import time\n\n import matplotlib.pyplot as plt\n\n import matplotlib\n from matplotlib import colors\n\n xmin, xmax, xn = -2.25, +0.75, 3000 // 2\n ymin, ymax, yn = -1.25, +1.25, 2500 // 2\n maxiter = 200\n horizon = 2.0 ** 40\n log_horizon = np.log2(np.log(horizon))\n Z, N = mandelbrot_set(xmin, xmax, ymin, ymax, xn, yn, maxiter, horizon)\n\n # Normalized recount as explained in:\n # https://linas.org/art-gallery/escape/smooth.html\n # https://web.archive.org/web/20160331171238/https://www.ibm.com/developerworks/community/blogs/jfp/entry/My_Christmas_Gift?lang=en\n\n # This line will generate warnings for null values, but it is faster to\n # process them afterwards using the nan_to_num\n with np.errstate(invalid='ignore'):\n M = np.nan_to_num(N + 1 - np.log2(np.log(abs(Z))) + log_horizon)\n\n dpi = 72\n width = 10\n height = 10*yn/xn\n fig = plt.figure(figsize=(width, height), dpi=dpi)\n ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1)\n\n # Shaded rendering\n light = colors.LightSource(azdeg=315, altdeg=10)\n M = light.shade(M, cmap=plt.cm.hot, vert_exag=1.5,\n norm=colors.PowerNorm(0.3), blend_mode='hsv')\n ax.imshow(M, extent=[xmin, xmax, ymin, ymax], interpolation=\"bicubic\")\n ax.set_xticks([])\n ax.set_yticks([])\n\n # Some advertisement for matplotlib\n year = time.strftime(\"%Y\")\n text = (\"The Mandelbrot fractal set\\n\"\n \"Rendered with matplotlib %s, %s - https://matplotlib.org\"\n % (matplotlib.__version__, year))\n ax.text(xmin+.025, ymin+.025, text, color=\"white\", fontsize=12, alpha=0.5)\n\n plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.2" } }, "nbformat": 4, "nbformat_minor": 0 }