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