|
3 | 3 | Scatter plot with histograms
|
4 | 4 | ============================
|
5 | 5 |
|
6 |
| -Create a scatter plot with histograms to its sides. |
| 6 | +Show the marginal distributions of a scatter as histograms at the sides of |
| 7 | +the plot. |
| 8 | +
|
| 9 | +For a nice alignment of the main axes with the marginals, two options are shown |
| 10 | +below. |
| 11 | +
|
| 12 | +* the axes positions are defined in terms of rectangles in figure coordinates |
| 13 | +* the axes positions are defined via a gridspec |
| 14 | +
|
| 15 | +An alternative method to produce a similar figure using the ``axes_grid1`` |
| 16 | +toolkit is shown in the |
| 17 | +:doc:`/gallery/axes_grid1/scatter_hist_locatable_axes` example. |
| 18 | +
|
| 19 | +Let us first define a function that takes x and y data as input, as well |
| 20 | +as three axes, the main axes for the scatter, and two marginal axes. It will |
| 21 | +then create the scatter and histograms inside the provided axes. |
7 | 22 | """
|
| 23 | + |
8 | 24 | import numpy as np
|
9 | 25 | import matplotlib.pyplot as plt
|
10 | 26 |
|
11 | 27 | # Fixing random state for reproducibility
|
12 | 28 | np.random.seed(19680801)
|
13 | 29 |
|
14 |
| -# the random data |
| 30 | +# some random data |
15 | 31 | x = np.random.randn(1000)
|
16 | 32 | y = np.random.randn(1000)
|
17 | 33 |
|
| 34 | + |
| 35 | +def scatter_hist(x, y, axScatter, axHistx, axHisty): |
| 36 | + # no labels |
| 37 | + axHistx.tick_params(axis="x", labelbottom=False) |
| 38 | + axHisty.tick_params(axis="y", labelleft=False) |
| 39 | + |
| 40 | + # the scatter plot: |
| 41 | + axScatter.scatter(x, y) |
| 42 | + |
| 43 | + # now determine nice limits by hand: |
| 44 | + binwidth = 0.25 |
| 45 | + xymax = max(np.max(np.abs(x)), np.max(np.abs(y))) |
| 46 | + lim = (int(xymax/binwidth) + 1) * binwidth |
| 47 | + |
| 48 | + bins = np.arange(-lim, lim + binwidth, binwidth) |
| 49 | + axHistx.hist(x, bins=bins) |
| 50 | + axHisty.hist(y, bins=bins, orientation='horizontal') |
| 51 | + |
| 52 | + |
| 53 | +############################################################################# |
| 54 | +# |
| 55 | +# Axes in figure coordinates |
| 56 | +# -------------------------- |
| 57 | +# |
| 58 | +# To define the axes positions `Figure.add_axes` is provided with a rectangle |
| 59 | +# ``[left, bottom, width, height]`` in figure coordinates. The marginal axes |
| 60 | +# share one dimension with the main axes. |
| 61 | + |
18 | 62 | # definitions for the axes
|
19 | 63 | left, width = 0.1, 0.65
|
20 | 64 | bottom, height = 0.1, 0.65
|
|
25 | 69 | rect_histx = [left, bottom + height + spacing, width, 0.2]
|
26 | 70 | rect_histy = [left + width + spacing, bottom, 0.2, height]
|
27 | 71 |
|
28 |
| -# start with a rectangular Figure |
29 |
| -plt.figure(figsize=(8, 8)) |
| 72 | +# start with a square Figure |
| 73 | +fig = plt.figure(figsize=(8, 8)) |
| 74 | + |
| 75 | +axScatter = fig.add_axes(rect_scatter) |
| 76 | +axHistx = fig.add_axes(rect_histx, sharex=axScatter) |
| 77 | +axHisty = fig.add_axes(rect_histy, sharey=axScatter) |
| 78 | + |
| 79 | +# use the previously defined function |
| 80 | +scatter_hist(x, y, axScatter, axHistx, axHisty) |
| 81 | + |
| 82 | +plt.show() |
| 83 | + |
30 | 84 |
|
31 |
| -ax_scatter = plt.axes(rect_scatter) |
32 |
| -ax_scatter.tick_params(direction='in', top=True, right=True) |
33 |
| -ax_histx = plt.axes(rect_histx) |
34 |
| -ax_histx.tick_params(direction='in', labelbottom=False) |
35 |
| -ax_histy = plt.axes(rect_histy) |
36 |
| -ax_histy.tick_params(direction='in', labelleft=False) |
| 85 | +############################################################################# |
| 86 | +# |
| 87 | +# Using a gridspec |
| 88 | +# ---------------- |
| 89 | +# |
| 90 | +# We may equally define a gridspec with unequal width- and height-ratios to |
| 91 | +# achieve desired layout. Also see the :doc:`/tutorials/intermediate/gridspec` |
| 92 | +# tutorial. |
37 | 93 |
|
38 |
| -# the scatter plot: |
39 |
| -ax_scatter.scatter(x, y) |
| 94 | +# start with a square Figure |
| 95 | +fig = plt.figure(figsize=(8, 8)) |
40 | 96 |
|
41 |
| -# now determine nice limits by hand: |
42 |
| -binwidth = 0.25 |
43 |
| -lim = np.ceil(np.abs([x, y]).max() / binwidth) * binwidth |
44 |
| -ax_scatter.set_xlim((-lim, lim)) |
45 |
| -ax_scatter.set_ylim((-lim, lim)) |
| 97 | +# Add a gridspec with two rows and two columns and a ratio of 2 to 7 between |
| 98 | +# the size of the marginal axes and the main axes in both directions. |
| 99 | +# Also adjust the subplot parameters for a square plot. |
| 100 | +gs = fig.add_gridspec(2, 2, width_ratios=(7, 2), height_ratios=(2, 7), |
| 101 | + left=0.1, right=0.9, bottom=0.1, top=0.9, |
| 102 | + wspace=0.05, hspace=0.05) |
46 | 103 |
|
47 |
| -bins = np.arange(-lim, lim + binwidth, binwidth) |
48 |
| -ax_histx.hist(x, bins=bins) |
49 |
| -ax_histy.hist(y, bins=bins, orientation='horizontal') |
| 104 | +axScatter = fig.add_subplot(gs[1, 0]) |
| 105 | +axHistx = fig.add_subplot(gs[0, 0], sharex=axScatter) |
| 106 | +axHisty = fig.add_subplot(gs[1, 1], sharey=axScatter) |
50 | 107 |
|
51 |
| -ax_histx.set_xlim(ax_scatter.get_xlim()) |
52 |
| -ax_histy.set_ylim(ax_scatter.get_ylim()) |
| 108 | +# use the previously defined function |
| 109 | +scatter_hist(x, y, axScatter, axHistx, axHisty) |
53 | 110 |
|
54 | 111 | plt.show()
|
| 112 | + |
| 113 | + |
| 114 | +############################################################################# |
| 115 | +# |
| 116 | +# ------------ |
| 117 | +# |
| 118 | +# References |
| 119 | +# """""""""" |
| 120 | +# |
| 121 | +# The use of the following functions, methods and classes is shown |
| 122 | +# in this example: |
| 123 | + |
| 124 | +import matplotlib |
| 125 | +matplotlib.figure.Figure.add_axes |
| 126 | +matplotlib.figure.Figure.add_subplot |
| 127 | +matplotlib.figure.Figure.add_gridspec |
| 128 | +matplotlib.axes.Axes.scatter |
| 129 | +matplotlib.axes.Axes.hist |
0 commit comments