/usr/lib/python3/dist-packages/astroML/plotting/scatter_contour.py is in python3-astroml 0.3-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | import numpy as np
def scatter_contour(x, y,
levels=10,
threshold=100,
log_counts=False,
histogram2d_args=None,
plot_args=None,
contour_args=None,
filled_contour=True,
ax=None):
"""Scatter plot with contour over dense regions
Parameters
----------
x, y : arrays
x and y data for the contour plot
levels : integer or array (optional, default=10)
number of contour levels, or array of contour levels
threshold : float (default=100)
number of points per 2D bin at which to begin drawing contours
log_counts :boolean (optional)
if True, contour levels are the base-10 logarithm of bin counts.
histogram2d_args : dict
keyword arguments passed to numpy.histogram2d
see doc string of numpy.histogram2d for more information
plot_args : dict
keyword arguments passed to plt.plot. By default it will use
dict(marker='.', linestyle='none').
see doc string of pylab.plot for more information
contour_args : dict
keyword arguments passed to plt.contourf or plt.contour
see doc string of pylab.contourf for more information
filled_contour : bool
If True (default) use filled contours. Otherwise, use contour outlines.
ax : pylab.Axes instance
the axes on which to plot. If not specified, the current
axes will be used
Returns
-------
points, contours :
points is the return value of ax.plot()
contours is the return value of ax.contour or ax.contourf
"""
x = np.asarray(x)
y = np.asarray(y)
default_plot_args = dict(marker='.', linestyle='none')
if plot_args is not None:
default_plot_args.update(plot_args)
plot_args = default_plot_args
if histogram2d_args is None:
histogram2d_args = {}
if contour_args is None:
contour_args = {}
if ax is None:
# Import here so that testing with Agg will work
from matplotlib import pyplot as plt
ax = plt.gca()
H, xbins, ybins = np.histogram2d(x, y, **histogram2d_args)
Nx = len(xbins)
Ny = len(ybins)
if log_counts:
H = np.log10(1 + H)
threshold = np.log10(1 + threshold)
levels = np.asarray(levels)
if levels.size == 1:
levels = np.linspace(threshold, H.max(), levels)
extent = [xbins[0], xbins[-1], ybins[0], ybins[-1]]
i_min = np.argmin(levels)
# draw a zero-width line: this gives us the outer polygon to
# reduce the number of points we draw
# somewhat hackish... we could probably get the same info from
# the full contour plot below.
outline = ax.contour(H.T, levels[i_min:i_min + 1],
linewidths=0, extent=extent)
if filled_contour:
contours = ax.contourf(H.T, levels, extent=extent, **contour_args)
else:
contours = ax.contour(H.T, levels, extent=extent, **contour_args)
X = np.hstack([x[:, None], y[:, None]])
if len(outline.allsegs[0]) > 0:
outer_poly = outline.allsegs[0][0]
try:
# this works in newer matplotlib versions
from matplotlib.path import Path
points_inside = Path(outer_poly).contains_points(X)
except:
# this works in older matplotlib versions
import matplotlib.nxutils as nx
points_inside = nx.points_inside_poly(X, outer_poly)
Xplot = X[~points_inside]
else:
Xplot = X
points = ax.plot(Xplot[:, 0], Xplot[:, 1], zorder=1, **plot_args)
return points, contours
|