From 19d4421cc984d321d2b19d5ca640f4a959661cf1 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 2 Nov 2024 15:04:41 -0700 Subject: [PATCH 1/2] DOC: just new labels --- galleries/examples/images_contours_and_fields/contour_demo.py | 2 ++ .../examples/images_contours_and_fields/contourf_demo.py | 1 + galleries/examples/images_contours_and_fields/contourf_log.py | 2 ++ .../examples/images_contours_and_fields/image_antialiasing.py | 4 ++++ galleries/examples/images_contours_and_fields/image_demo.py | 2 ++ galleries/examples/images_contours_and_fields/pcolor_demo.py | 2 ++ .../examples/images_contours_and_fields/pcolormesh_grids.py | 2 ++ .../examples/images_contours_and_fields/plot_streamplot.py | 2 ++ .../examples/images_contours_and_fields/tricontour_demo.py | 2 ++ .../images_contours_and_fields/tricontour_smooth_delaunay.py | 2 ++ .../images_contours_and_fields/tricontour_smooth_user.py | 2 ++ .../examples/images_contours_and_fields/tripcolor_demo.py | 2 ++ galleries/examples/images_contours_and_fields/triplot_demo.py | 2 ++ .../examples/lines_bars_and_markers/categorical_variables.py | 2 ++ galleries/examples/lines_bars_and_markers/eventplot_demo.py | 2 ++ .../examples/lines_bars_and_markers/fill_between_demo.py | 2 ++ galleries/examples/lines_bars_and_markers/step_demo.py | 2 ++ galleries/examples/mplot3d/bars3d.py | 2 ++ galleries/examples/mplot3d/box3d.py | 2 ++ galleries/examples/mplot3d/custom_shaded_3d_surface.py | 2 ++ galleries/examples/mplot3d/intersecting_planes.py | 2 ++ galleries/examples/mplot3d/quiver3d.py | 2 ++ galleries/examples/mplot3d/stem3d_demo.py | 2 ++ galleries/examples/mplot3d/surface3d.py | 2 ++ galleries/examples/mplot3d/surface3d_2.py | 2 ++ galleries/examples/mplot3d/surface3d_3.py | 2 ++ galleries/examples/mplot3d/trisurf3d.py | 2 ++ galleries/examples/mplot3d/trisurf3d_2.py | 2 ++ galleries/examples/statistics/boxplot.py | 2 ++ galleries/examples/statistics/boxplot_color.py | 2 ++ galleries/examples/statistics/boxplot_demo.py | 2 ++ galleries/examples/statistics/boxplot_vs_violin.py | 2 ++ galleries/examples/statistics/customized_violin.py | 2 ++ galleries/examples/statistics/hexbin_demo.py | 2 ++ galleries/examples/statistics/histogram_histtypes.py | 2 ++ galleries/examples/statistics/histogram_multihist.py | 2 ++ galleries/examples/statistics/histogram_normalization.py | 1 + galleries/examples/statistics/violinplot.py | 2 ++ galleries/plot_types/3D/bar3d_simple.py | 2 ++ galleries/plot_types/3D/surface3d_simple.py | 2 ++ galleries/plot_types/3D/trisurf3d_simple.py | 2 ++ galleries/plot_types/arrays/pcolormesh.py | 3 +++ galleries/users_explain/artists/index.rst | 2 ++ galleries/users_explain/axes/index.rst | 2 ++ 44 files changed, 89 insertions(+) diff --git a/galleries/examples/images_contours_and_fields/contour_demo.py b/galleries/examples/images_contours_and_fields/contour_demo.py index 05fd3d5e3be8..02db17d9cdd4 100644 --- a/galleries/examples/images_contours_and_fields/contour_demo.py +++ b/galleries/examples/images_contours_and_fields/contour_demo.py @@ -1,4 +1,6 @@ """ +.. _contour_demo: + ============ Contour Demo ============ diff --git a/galleries/examples/images_contours_and_fields/contourf_demo.py b/galleries/examples/images_contours_and_fields/contourf_demo.py index 18c13d922e38..a0068718ad41 100644 --- a/galleries/examples/images_contours_and_fields/contourf_demo.py +++ b/galleries/examples/images_contours_and_fields/contourf_demo.py @@ -1,4 +1,5 @@ """ +.. _contourf_demo: ============= Contourf demo ============= diff --git a/galleries/examples/images_contours_and_fields/contourf_log.py b/galleries/examples/images_contours_and_fields/contourf_log.py index 408976adb9c2..841ea5ae60f2 100644 --- a/galleries/examples/images_contours_and_fields/contourf_log.py +++ b/galleries/examples/images_contours_and_fields/contourf_log.py @@ -1,4 +1,6 @@ """ +.. _contourf_log: + ============================ Contourf and log color scale ============================ diff --git a/galleries/examples/images_contours_and_fields/image_antialiasing.py b/galleries/examples/images_contours_and_fields/image_antialiasing.py index 7f223f6998f2..4e6097b9ba0f 100644 --- a/galleries/examples/images_contours_and_fields/image_antialiasing.py +++ b/galleries/examples/images_contours_and_fields/image_antialiasing.py @@ -1,4 +1,8 @@ """ +.. _image_antialiasing: + +.. _image_resampling: + ================ Image resampling ================ diff --git a/galleries/examples/images_contours_and_fields/image_demo.py b/galleries/examples/images_contours_and_fields/image_demo.py index 4111adfa2c4e..49fa669cb315 100644 --- a/galleries/examples/images_contours_and_fields/image_demo.py +++ b/galleries/examples/images_contours_and_fields/image_demo.py @@ -1,4 +1,6 @@ """ +.. _image_demo: + ======================== Many ways to plot images ======================== diff --git a/galleries/examples/images_contours_and_fields/pcolor_demo.py b/galleries/examples/images_contours_and_fields/pcolor_demo.py index 7a8ef35caf96..1300dfee7ec7 100644 --- a/galleries/examples/images_contours_and_fields/pcolor_demo.py +++ b/galleries/examples/images_contours_and_fields/pcolor_demo.py @@ -1,4 +1,6 @@ """ +.. _pcolor_demo: + ============= pcolor images ============= diff --git a/galleries/examples/images_contours_and_fields/pcolormesh_grids.py b/galleries/examples/images_contours_and_fields/pcolormesh_grids.py index 212b807dbf90..91cc60720e71 100644 --- a/galleries/examples/images_contours_and_fields/pcolormesh_grids.py +++ b/galleries/examples/images_contours_and_fields/pcolormesh_grids.py @@ -1,4 +1,6 @@ """ +.. _pcolormesh_grids: + ============================ pcolormesh grids and shading ============================ diff --git a/galleries/examples/images_contours_and_fields/plot_streamplot.py b/galleries/examples/images_contours_and_fields/plot_streamplot.py index 0128b6369b4a..f9eaff7bd80e 100644 --- a/galleries/examples/images_contours_and_fields/plot_streamplot.py +++ b/galleries/examples/images_contours_and_fields/plot_streamplot.py @@ -1,4 +1,6 @@ """ +.. _plot_streamplot: + ========== Streamplot ========== diff --git a/galleries/examples/images_contours_and_fields/tricontour_demo.py b/galleries/examples/images_contours_and_fields/tricontour_demo.py index 3459382caad6..2cf36ba50618 100644 --- a/galleries/examples/images_contours_and_fields/tricontour_demo.py +++ b/galleries/examples/images_contours_and_fields/tricontour_demo.py @@ -1,4 +1,6 @@ """ +.. _tricontour_demo: + =============== Tricontour Demo =============== diff --git a/galleries/examples/images_contours_and_fields/tricontour_smooth_delaunay.py b/galleries/examples/images_contours_and_fields/tricontour_smooth_delaunay.py index 0f1ee4938f8d..6ad8b452ac27 100644 --- a/galleries/examples/images_contours_and_fields/tricontour_smooth_delaunay.py +++ b/galleries/examples/images_contours_and_fields/tricontour_smooth_delaunay.py @@ -1,4 +1,6 @@ """ +.. _tricontour_smooth_delaunay: + ========================== Tricontour Smooth Delaunay ========================== diff --git a/galleries/examples/images_contours_and_fields/tricontour_smooth_user.py b/galleries/examples/images_contours_and_fields/tricontour_smooth_user.py index 2d973c0de108..d58b7172d7ee 100644 --- a/galleries/examples/images_contours_and_fields/tricontour_smooth_user.py +++ b/galleries/examples/images_contours_and_fields/tricontour_smooth_user.py @@ -1,4 +1,6 @@ """ +.. _tricontour_smooth_user: + ====================== Tricontour Smooth User ====================== diff --git a/galleries/examples/images_contours_and_fields/tripcolor_demo.py b/galleries/examples/images_contours_and_fields/tripcolor_demo.py index a1c011a1224c..0672d086d943 100644 --- a/galleries/examples/images_contours_and_fields/tripcolor_demo.py +++ b/galleries/examples/images_contours_and_fields/tripcolor_demo.py @@ -1,4 +1,6 @@ """ +.. _tripcolor_demo: + ============== Tripcolor Demo ============== diff --git a/galleries/examples/images_contours_and_fields/triplot_demo.py b/galleries/examples/images_contours_and_fields/triplot_demo.py index e1151b37ac4a..9db21628fcce 100644 --- a/galleries/examples/images_contours_and_fields/triplot_demo.py +++ b/galleries/examples/images_contours_and_fields/triplot_demo.py @@ -1,4 +1,6 @@ """ +.. _triplot_demo: + ============ Triplot Demo ============ diff --git a/galleries/examples/lines_bars_and_markers/categorical_variables.py b/galleries/examples/lines_bars_and_markers/categorical_variables.py index a19a30eda2b2..2435417fe608 100644 --- a/galleries/examples/lines_bars_and_markers/categorical_variables.py +++ b/galleries/examples/lines_bars_and_markers/categorical_variables.py @@ -1,4 +1,6 @@ """ +.. _categorical_variables: + ============================== Plotting categorical variables ============================== diff --git a/galleries/examples/lines_bars_and_markers/eventplot_demo.py b/galleries/examples/lines_bars_and_markers/eventplot_demo.py index 17797c2f697a..eba72f17d29e 100644 --- a/galleries/examples/lines_bars_and_markers/eventplot_demo.py +++ b/galleries/examples/lines_bars_and_markers/eventplot_demo.py @@ -1,4 +1,6 @@ """ +.. _eventplot_demo: + ============== Eventplot demo ============== diff --git a/galleries/examples/lines_bars_and_markers/fill_between_demo.py b/galleries/examples/lines_bars_and_markers/fill_between_demo.py index feb325a3f9db..108e0fa20d21 100644 --- a/galleries/examples/lines_bars_and_markers/fill_between_demo.py +++ b/galleries/examples/lines_bars_and_markers/fill_between_demo.py @@ -1,4 +1,6 @@ """ +.. _fill_between_demo: + =============================== Fill the area between two lines =============================== diff --git a/galleries/examples/lines_bars_and_markers/step_demo.py b/galleries/examples/lines_bars_and_markers/step_demo.py index f74a069e52f3..2aba2cb6d37b 100644 --- a/galleries/examples/lines_bars_and_markers/step_demo.py +++ b/galleries/examples/lines_bars_and_markers/step_demo.py @@ -1,4 +1,6 @@ """ +.. _step_demo: + ========= Step Demo ========= diff --git a/galleries/examples/mplot3d/bars3d.py b/galleries/examples/mplot3d/bars3d.py index 3ea4a100c2f6..ba732e7e15cb 100644 --- a/galleries/examples/mplot3d/bars3d.py +++ b/galleries/examples/mplot3d/bars3d.py @@ -1,4 +1,6 @@ """ +.. _bars3d: + ======================================== Create 2D bar graphs in different planes ======================================== diff --git a/galleries/examples/mplot3d/box3d.py b/galleries/examples/mplot3d/box3d.py index 807e3d496ec6..c98084229416 100644 --- a/galleries/examples/mplot3d/box3d.py +++ b/galleries/examples/mplot3d/box3d.py @@ -1,4 +1,6 @@ """ +.. _box3d: + =================== 3D box surface plot =================== diff --git a/galleries/examples/mplot3d/custom_shaded_3d_surface.py b/galleries/examples/mplot3d/custom_shaded_3d_surface.py index e8d1a4f33d87..3dd254226b59 100644 --- a/galleries/examples/mplot3d/custom_shaded_3d_surface.py +++ b/galleries/examples/mplot3d/custom_shaded_3d_surface.py @@ -1,4 +1,6 @@ """ +.. _custom_shaded_3d_surface: + ======================================= Custom hillshading in a 3D surface plot ======================================= diff --git a/galleries/examples/mplot3d/intersecting_planes.py b/galleries/examples/mplot3d/intersecting_planes.py index a5a92caf5c6b..25e9573f5d84 100644 --- a/galleries/examples/mplot3d/intersecting_planes.py +++ b/galleries/examples/mplot3d/intersecting_planes.py @@ -1,4 +1,6 @@ """ +.. _intersecting_planes: + =================== Intersecting planes =================== diff --git a/galleries/examples/mplot3d/quiver3d.py b/galleries/examples/mplot3d/quiver3d.py index adc58c2e9d89..5655f12c734d 100644 --- a/galleries/examples/mplot3d/quiver3d.py +++ b/galleries/examples/mplot3d/quiver3d.py @@ -1,4 +1,6 @@ """ +.. _quiver3d: + ============== 3D quiver plot ============== diff --git a/galleries/examples/mplot3d/stem3d_demo.py b/galleries/examples/mplot3d/stem3d_demo.py index 82b45ff19068..a87a0ac69823 100644 --- a/galleries/examples/mplot3d/stem3d_demo.py +++ b/galleries/examples/mplot3d/stem3d_demo.py @@ -1,4 +1,6 @@ """ +.. _stem3d_demo: + ======= 3D stem ======= diff --git a/galleries/examples/mplot3d/surface3d.py b/galleries/examples/mplot3d/surface3d.py index 6c51a69c0d1f..5af89f876e1b 100644 --- a/galleries/examples/mplot3d/surface3d.py +++ b/galleries/examples/mplot3d/surface3d.py @@ -1,4 +1,6 @@ """ +.. _surface3d: + ===================== 3D surface (colormap) ===================== diff --git a/galleries/examples/mplot3d/surface3d_2.py b/galleries/examples/mplot3d/surface3d_2.py index 2a4406abc259..82365174c86d 100644 --- a/galleries/examples/mplot3d/surface3d_2.py +++ b/galleries/examples/mplot3d/surface3d_2.py @@ -1,4 +1,6 @@ """ +.. _surface3d_2: + ======================== 3D surface (solid color) ======================== diff --git a/galleries/examples/mplot3d/surface3d_3.py b/galleries/examples/mplot3d/surface3d_3.py index c129ef6d3635..57e541f249c2 100644 --- a/galleries/examples/mplot3d/surface3d_3.py +++ b/galleries/examples/mplot3d/surface3d_3.py @@ -1,4 +1,6 @@ """ +.. _surface3d_3: + ========================= 3D surface (checkerboard) ========================= diff --git a/galleries/examples/mplot3d/trisurf3d.py b/galleries/examples/mplot3d/trisurf3d.py index f4e7444a4311..3e754c217b05 100644 --- a/galleries/examples/mplot3d/trisurf3d.py +++ b/galleries/examples/mplot3d/trisurf3d.py @@ -1,4 +1,6 @@ """ +.. _trisurf3d: + ====================== Triangular 3D surfaces ====================== diff --git a/galleries/examples/mplot3d/trisurf3d_2.py b/galleries/examples/mplot3d/trisurf3d_2.py index 0e757140c20e..e597173fbca0 100644 --- a/galleries/examples/mplot3d/trisurf3d_2.py +++ b/galleries/examples/mplot3d/trisurf3d_2.py @@ -1,4 +1,6 @@ """ +.. _trisurf3d_2: + =========================== More triangular 3D surfaces =========================== diff --git a/galleries/examples/statistics/boxplot.py b/galleries/examples/statistics/boxplot.py index 6d30cbd4b5f0..10255182fe34 100644 --- a/galleries/examples/statistics/boxplot.py +++ b/galleries/examples/statistics/boxplot.py @@ -1,4 +1,6 @@ """ +.. _boxplot_artists: + ================================= Artist customization in box plots ================================= diff --git a/galleries/examples/statistics/boxplot_color.py b/galleries/examples/statistics/boxplot_color.py index acdb37d7d520..1475480e802e 100644 --- a/galleries/examples/statistics/boxplot_color.py +++ b/galleries/examples/statistics/boxplot_color.py @@ -1,4 +1,6 @@ """ +.. _boxplot_color: + ================================= Box plots with custom fill colors ================================= diff --git a/galleries/examples/statistics/boxplot_demo.py b/galleries/examples/statistics/boxplot_demo.py index b642d7e9f658..0f5c7f44403d 100644 --- a/galleries/examples/statistics/boxplot_demo.py +++ b/galleries/examples/statistics/boxplot_demo.py @@ -1,4 +1,6 @@ """ +.. _boxplot_demo: + ======== Boxplots ======== diff --git a/galleries/examples/statistics/boxplot_vs_violin.py b/galleries/examples/statistics/boxplot_vs_violin.py index f277e737e65c..434d8ee77e0d 100644 --- a/galleries/examples/statistics/boxplot_vs_violin.py +++ b/galleries/examples/statistics/boxplot_vs_violin.py @@ -1,4 +1,6 @@ """ +.. _boxplot_vs_violin: + =================================== Box plot vs. violin plot comparison =================================== diff --git a/galleries/examples/statistics/customized_violin.py b/galleries/examples/statistics/customized_violin.py index cc18e47ebd67..4ec9f4b11c1b 100644 --- a/galleries/examples/statistics/customized_violin.py +++ b/galleries/examples/statistics/customized_violin.py @@ -1,4 +1,6 @@ """ +.. _customized_violin: + ========================= Violin plot customization ========================= diff --git a/galleries/examples/statistics/hexbin_demo.py b/galleries/examples/statistics/hexbin_demo.py index bd1522772aae..879d92cd8d37 100644 --- a/galleries/examples/statistics/hexbin_demo.py +++ b/galleries/examples/statistics/hexbin_demo.py @@ -1,4 +1,6 @@ """ +.. _hexbin_demo: + ===================== Hexagonal binned plot ===================== diff --git a/galleries/examples/statistics/histogram_histtypes.py b/galleries/examples/statistics/histogram_histtypes.py index 53d6425cf4dc..c365b1ed9e93 100644 --- a/galleries/examples/statistics/histogram_histtypes.py +++ b/galleries/examples/statistics/histogram_histtypes.py @@ -1,4 +1,6 @@ """ +.. _histogram_histtypes: + ================================================================ Demo of the histogram function's different ``histtype`` settings ================================================================ diff --git a/galleries/examples/statistics/histogram_multihist.py b/galleries/examples/statistics/histogram_multihist.py index a85ec2acfa8d..36b770deff49 100644 --- a/galleries/examples/statistics/histogram_multihist.py +++ b/galleries/examples/statistics/histogram_multihist.py @@ -1,4 +1,6 @@ """ +.. _histogram_multihist: + ===================================================== The histogram (hist) function with multiple data sets ===================================================== diff --git a/galleries/examples/statistics/histogram_normalization.py b/galleries/examples/statistics/histogram_normalization.py index 2c423edad208..f511809f6ae3 100644 --- a/galleries/examples/statistics/histogram_normalization.py +++ b/galleries/examples/statistics/histogram_normalization.py @@ -1,5 +1,6 @@ """ .. redirect-from:: /gallery/statistics/histogram_features +.. _histogram_normalization: =================================== Histogram bins, density, and weight diff --git a/galleries/examples/statistics/violinplot.py b/galleries/examples/statistics/violinplot.py index 7f4725ff7a8c..e0becd10ddf7 100644 --- a/galleries/examples/statistics/violinplot.py +++ b/galleries/examples/statistics/violinplot.py @@ -1,4 +1,6 @@ """ +.. _violinplot: + ================== Violin plot basics ================== diff --git a/galleries/plot_types/3D/bar3d_simple.py b/galleries/plot_types/3D/bar3d_simple.py index aa75560de8f2..db0ca2c8a712 100644 --- a/galleries/plot_types/3D/bar3d_simple.py +++ b/galleries/plot_types/3D/bar3d_simple.py @@ -1,4 +1,6 @@ """ +.. _bar3d_simple: + ========================== bar3d(x, y, z, dx, dy, dz) ========================== diff --git a/galleries/plot_types/3D/surface3d_simple.py b/galleries/plot_types/3D/surface3d_simple.py index c887b042da94..c46f442a224e 100644 --- a/galleries/plot_types/3D/surface3d_simple.py +++ b/galleries/plot_types/3D/surface3d_simple.py @@ -1,4 +1,6 @@ """ +.. _surface3d_simple: + ===================== plot_surface(X, Y, Z) ===================== diff --git a/galleries/plot_types/3D/trisurf3d_simple.py b/galleries/plot_types/3D/trisurf3d_simple.py index f5252699ac23..970ee5bfdc57 100644 --- a/galleries/plot_types/3D/trisurf3d_simple.py +++ b/galleries/plot_types/3D/trisurf3d_simple.py @@ -1,4 +1,6 @@ """ +.. _trisurf3d_simple: + ===================== plot_trisurf(x, y, z) ===================== diff --git a/galleries/plot_types/arrays/pcolormesh.py b/galleries/plot_types/arrays/pcolormesh.py index 4f0913f62521..8ac1fcdf35f2 100644 --- a/galleries/plot_types/arrays/pcolormesh.py +++ b/galleries/plot_types/arrays/pcolormesh.py @@ -1,7 +1,10 @@ """ +.. _pcolormesh: + =================== pcolormesh(X, Y, Z) =================== + Create a pseudocolor plot with a non-regular rectangular grid. `~.axes.Axes.pcolormesh` is more flexible than `~.axes.Axes.imshow` in that diff --git a/galleries/users_explain/artists/index.rst b/galleries/users_explain/artists/index.rst index d3f2918c9a91..dacfa9f13aa7 100644 --- a/galleries/users_explain/artists/index.rst +++ b/galleries/users_explain/artists/index.rst @@ -1,3 +1,5 @@ +.. _users-guide-artists: + +++++++ Artists +++++++ diff --git a/galleries/users_explain/axes/index.rst b/galleries/users_explain/axes/index.rst index a3683d69ec5a..08662e89f44c 100644 --- a/galleries/users_explain/axes/index.rst +++ b/galleries/users_explain/axes/index.rst @@ -1,3 +1,5 @@ +.. _users_guide_axes: + +++++++++++++++++ Axes and subplots +++++++++++++++++ From f3a6f5391be80a592cec54ab9936b98e0da72431 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 2 Nov 2024 15:04:41 -0700 Subject: [PATCH 2/2] DOC: user guide section on plotting methods --- doc/users/index.rst | 9 + galleries/users_explain/plotting/gridded.py | 275 ++++++++++++++ galleries/users_explain/plotting/index.rst | 169 +++++++++ galleries/users_explain/plotting/pairwise.py | 337 ++++++++++++++++++ .../users_explain/plotting/statistical.py | 281 +++++++++++++++ galleries/users_explain/plotting/threed.py | 249 +++++++++++++ .../plotting/unstructuredgrid.py | 123 +++++++ 7 files changed, 1443 insertions(+) create mode 100644 galleries/users_explain/plotting/gridded.py create mode 100644 galleries/users_explain/plotting/index.rst create mode 100644 galleries/users_explain/plotting/pairwise.py create mode 100644 galleries/users_explain/plotting/statistical.py create mode 100644 galleries/users_explain/plotting/threed.py create mode 100644 galleries/users_explain/plotting/unstructuredgrid.py diff --git a/doc/users/index.rst b/doc/users/index.rst index 2991e7d2b324..2f0fd089cab3 100644 --- a/doc/users/index.rst +++ b/doc/users/index.rst @@ -42,6 +42,15 @@ Using Matplotlib explain/axes/index + .. grid-item-card:: + :padding: 2 + + .. toctree:: + :maxdepth: 2 + :includehidden: + + explain/plotting/index + .. grid-item-card:: :padding: 2 diff --git a/galleries/users_explain/plotting/gridded.py b/galleries/users_explain/plotting/gridded.py new file mode 100644 index 000000000000..1cc931ced700 --- /dev/null +++ b/galleries/users_explain/plotting/gridded.py @@ -0,0 +1,275 @@ +""" +.. _plot_gridded: + +Gridded plots +============= + +This section discusses data that mapped onto a two-dimensional grid. The data +usually has structured coordinates defined by arrays of x and y values, and data +mapped onto those coordinates :math:`Data(x, y)` in a two-dimensional array. The grid +can either be regular, in which case the x and y arrays are 1D and the Data is 2D, +or the grid can be irregular, and X, Y, and Data are all 2D arrays. + +""" + +import matplotlib.pyplot as plt +import numpy as np + +import warnings + +plt.rcParams['figure.constrained_layout.use'] = True +plt.rcParams['figure.figsize'] = (5, 4) + +# %% +# imshow +# ------ +# +# `~.axes.Axes.imshow` is a simple way to plot a 2D array as an image. By +# default, the aspect ratio is set to be equal, so the pixels are square, and +# the origin of the data is the upper-left corner. The values of the array are +# mapped to colors using a colormap. + +# create a square matrix of data: +X, Y = np.meshgrid(np.linspace(-3, 3, 128), np.linspace(-3, 3, 128)) +Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2) + +fig, ax = plt.subplots() +im = ax.imshow(Z) +fig.colorbar(im, ax=ax) +ax.set_xlabel('pixels in x') +ax.set_ylabel('pixels in y') + +# %% +# +# Note how the origin is in the upper left and the x and y axises are in units +# of pixels. These behaviors can be changed with the *origin* and *extent* +# arguments. This is discussed in detail in :ref:`imshow_extent`. +# +# Other colormaps can be chosen through the *cmap* argument (see +# :ref:`colormaps`), and the color limits can be set with the *vmin* and *vmax* +# arguments, or by using the *norm* parameter (see :ref:`colormapnorms`). An example +# of using *vmin* and *vmax* is shown below: + +fig, ax = plt.subplots() +im = ax.imshow(Z, cmap='RdBu_r', vmin=-1, vmax=1) +fig.colorbar(im, ax=ax) +ax.set_xlabel('pixels in x') +ax.set_ylabel('pixels in y') + +# %% +# +# There are many options for resampling the data when it is displayed. See +# :ref:`image_antialiasing` for more information, but note the the default attempts +# to remove aliasing artifacts from data that is "downsampled" (i.e., when the +# number of pixels in the data array is greater than the number of pixels in the +# displayed image). +# +# .. seealso:: +# - :ref:`image_demo` +# - :ref:`imshow_extent` +# - :ref:`image_antialiasing` + + +# %% +# pcolormesh (and pcolor, pcolorfast) +# ----------------------------------- +# +# `~.axes.Axes.pcolormesh` is more flexible than `~.axes.Axes.imshow` in that +# the x and y vectors need not be equally spaced (indeed they can be skewed). +# In the example below, the x values are unevenly spaced, and much less finely +# sampled than the y values. The x and y data are orthogonal, so we can pass +# x and y directly to `~.axes.Axes.pcolormesh`: + +x = np.array([-3, -2, -1.6, -1.2, -.8, -.5, -.2, .1, .3, .5, .8, 1.1, 1.5, 1.9, 2.3, 3]) +y = np.linspace(-3, 3, 128) +X, Y = np.meshgrid(x, y) +Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2) + +fig, ax = plt.subplots() + +ax.pcolormesh(x, y, Z, vmin=-0.5, vmax=1.0) + +ax.set_xlabel('x') +ax.set_ylabel('y') + +# %% +# As noted, `~.axes.Axes.pcolormesh` need not be on an orthogonal grid. Here +# is an example with the y grid points varying with x. Note that we need to +# give the grids as 2D arrays for this to work: + +# make a 2D array of y values that where the y dimension varies in x: +Yn = Y + 0.3 * np.abs(x) + +fig, ax = plt.subplots() +with warnings.catch_warnings(): + warnings.simplefilter("ignore") + ax.pcolormesh(X, Yn, Z, vmin=-0.5, vmax=1.0) +ax.set_xlabel('x') +ax.set_ylabel('skewed y') + +# %% +# Note that the above returns a warning because the y grid is not strictly increasing: +# +# UserWarning: The input coordinates to pcolormesh are +# interpreted as cell centers, but are not monotonically +# increasing or decreasing. +# +# To avoid that warning, we can give `.Axes.pcolormesh` the cell edges rather +# than the cell centers: + + +def midpoints_plus_ends(x): + """Given a 1D array, return a new array with the midpoints and the two ends.""" + return np.concatenate(([x[0] - (x[1] - x[0]) / 2], + x[:-1] + np.diff(x) / 2, + [x[-1] - (x[-1] - x[-2]) / 2])) + +yn = midpoints_plus_ends(y) +xn = midpoints_plus_ends(x) +Xn, Yn = np.meshgrid(xn, yn) +Yn = Yn + 0.3 * np.abs(xn) + +fig, ax = plt.subplots() +ax.pcolormesh(Xn, Yn, Z, vmin=-0.5, vmax=1.0) + +# %% +# Two similar methods are `~.axes.Axes.pcolor` and `~.axes.Axes.pcolorfast`. There are +# some differences in the way they handle the data, but they are largely the same and +# are not as commonly used as `~.axes.Axes.pcolormesh`. See +# :ref:`Differences between pcolor() and pcolormesh() ` +# for a discussion of the differences. +# +# `~.axes.Axes.pcolorfast` is not as flexible as `~.axes.Axes.pcolormesh`, but can be +# faster for large datasets. + +# %% +# .. seealso:: +# - :ref:`pcolormesh_grids` +# - :ref:`pcolor_demo` + +# %% +# contour and contourf +# -------------------- +# +# `~.axes.Axes.contour` and `~.axes.Axes.contourf` create contour plots. They accept +# a 2D array of data, and create a plot with contour lines or filled regions enclosing +# data that is in the same contour level. The example below shows a simple contour +# plot using the data from above. Note that as before, the x and y data are not +# necessarily evenly spaced, but in this case they are orthogonal. + +fig, axs = plt.subplots(2, 1, figsize=(5, 5)) +ax = axs[0] +ax.contour(x, y, Z, levels=10) +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('contour plot') + +ax = axs[1] +cf = ax.contourf(x, y, Z, levels=10) +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('contourf plot') +fig.colorbar(cf, ax=ax) + +# %% +# Note that like for `.Axes.pcolormesh`, the grid need not be orthogonal. In +# the following example the the same data is plotted as above, but with the y +# grid points varying with x. The contour *levels* are also manually specified +# in this example with a list of levels, (see :ref:`contourf_log` for an +# example of using a tick locator instead of a list), and the colormap set with +# the *cmap* argument (see :ref:`colormaps`). + +Yn = Y + 0.3 * np.abs(x) + +fig, ax = plt.subplots() + +cf = ax.contourf(X, Yn, Z, levels=np.arange(-1.3, 1.31, 0.2), cmap='RdBu_r') +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('contour plot') +fig.colorbar(cf, ax=ax) + +# %% +# .. seealso:: +# +# - :ref:`contour_demo` +# - :ref:`contourf_demo` + +# %% +# barbs and quiver +# ---------------- +# `~.axes.Axes.barbs` and `~.axes.Axes.quiver` allow us to represent gridded +# vector fields specified at points on an x-y grid by two-dimensional arrays U, +# V. The arrays must be the same shape as x and y and the arrows are placed at +# the corresponding points in the grid. The main difference between the two +# functions is that `~.axes.Axes.barbs` plots barbs, which are a more +# traditional representation of wind speed and direction, while +# `~.axes.Axes.quiver` plots arrows with a uniform size and the direction is +# given by the vector U, V. + +# make data +x = np.linspace(-4, 4, 20) +y = np.linspace(-4, 4, 20) +X, Y = np.meshgrid(x, y) +U = X + Y +V = Y - X + +# plot +fig, ax = plt.subplots() + +ax.quiver(X, Y, U, V, color="C0", angles='xy', + scale_units='xy', scale=8, width=.005) + +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('barbs') + +fig, ax = plt.subplots() +ax.barbs(X, Y, U, V, color="C0", barbcolor='C0', flagcolor='C0', length=4, + linewidth=1.0) + +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('quiver') + +# %% +# streamplot +# ---------- +# +# `~.axes.Axes.streamplot` is used to plot the streamlines of a vector field. It +# makes traces of where a massless particle would go if it followed the vector field +# at each point. The example below shows the streamlines of the vector field from +# above: + +fig, ax = plt.subplots() +ax.streamplot(x, y, U, V) + +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('streamplot') + +# %% +# `~.axes.Axes.streamplot` performs an interpolation and the streamlines are +# not guaranteed to be accurate. For more accurate streamlines, the data grid +# could be refined. +# +# .. note:: +# +# `~.axes.Axes.streamplot` does not accept 2D arrays for the x and y data: +# the x and y data must be 1D arrays, and the spacing between the points must +# be uniform. +# +# .. seealso:: :ref:`Streamplot demo ` +# +# .. admonition:: References +# +# The use of the following functions, methods, classes and modules is shown +# in this example: +# +# - `matplotlib.axes.Axes.imshow` / `matplotlib.pyplot.imshow` +# - `matplotlib.axes.Axes.pcolormesh` / `matplotlib.pyplot.pcolormesh` +# - `matplotlib.axes.Axes.contour` / `matplotlib.pyplot.contour` +# - `matplotlib.axes.Axes.contourf` / `matplotlib.pyplot.contourf` +# - `matplotlib.axes.Axes.barbs` / `matplotlib.pyplot.barbs` +# - `matplotlib.axes.Axes.quiver` / `matplotlib.pyplot.quiver` +# - `matplotlib.axes.Axes.streamplot` / `matplotlib.pyplot.streamplot` diff --git a/galleries/users_explain/plotting/index.rst b/galleries/users_explain/plotting/index.rst new file mode 100644 index 000000000000..d3e27c55861f --- /dev/null +++ b/galleries/users_explain/plotting/index.rst @@ -0,0 +1,169 @@ +++++++++++++++++ +Plotting methods +++++++++++++++++ + +.. _users-guide-plotting: + +Matplotlib can create a wide variety of data visualizations, many of which are +previewed in the :ref:`plot_types` gallery. This section provides an overview +on working with these visualizations. More details and examples can be found +in the :ref:`gallery` gallery, and general advice about :ref:`users_guide_axes` +and :ref:`users-guide-artists` can be found in other sections of :ref:`the +user's guide `. + +.. grid:: 1 1 2 2 + + .. grid-item-card:: + :padding: 2 + + .. toctree:: + :maxdepth: 2 + :includehidden: + + pairwise + + .. grid-item-card:: + :padding: 2 + + .. plot:: + :height: 7em + + import matplotlib.pyplot as plt + import numpy as np + + fig, ax = plt.subplots(figsize=(3, 1.7), layout="constrained") + rng = np.random.default_rng(seed=19680801) + ax.plot(np.arange(200), np.cumsum(rng.normal(size=200))) + ax.set_xlabel('time') + ax.set_ylabel('random walk') + + .. grid-item-card:: + :padding: 2 + + + .. toctree:: + :maxdepth: 2 + :includehidden: + + statistical + + .. grid-item-card:: + :padding: 2 + + .. plot:: + :height: 7em + + import matplotlib.pyplot as plt + import numpy as np + + fig, ax = plt.subplots(figsize=(3.5, 1.7), layout="constrained") + rng = np.random.default_rng(seed=19680801) + ax.hist(rng.normal(size=200), density=True) + ax.set_xlabel('x') + ax.set_ylabel('pdf') + + .. grid-item-card:: + :padding: 2 + + .. toctree:: + :maxdepth: 2 + :includehidden: + + gridded + + .. grid-item-card:: + :padding: 2 + + + .. plot:: + :height: 7em + + import matplotlib.pyplot as plt + import numpy as np + + + # make data with uneven sampling in x + x = [-3, -2, -1.6, -1.2, -.8, -.5, -.2, .1, .3, .5, .8, 1.1, 1.5, 1.9, 2.3, 3] + X, Y = np.meshgrid(x, np.linspace(-3, 3, 128)) + Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2) + + fig, ax = plt.subplots(figsize=(3.5, 1.7), layout="constrained") + + ax.pcolormesh(X, Y, Z, vmin=-0.5, vmax=1.0) + ax.set_xlabel('x') + ax.set_ylabel('y') + + ax.contour(X, Y, Z, vmin=-0.5, vmax=1.0, linewidths=2, cmap='RdBu_r') + + + .. grid-item-card:: + :padding: 2 + + .. toctree:: + :maxdepth: 2 + :includehidden: + + unstructuredgrid + + .. grid-item-card:: + :padding: 2 + + .. plot:: + :height: 7em + + import matplotlib.pyplot as plt + import numpy as np + + # make data: + np.random.seed(1) + x = np.random.uniform(-3, 3, 256) + y = np.random.uniform(-3, 3, 256) + z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2) + + # plot: + fig, ax = plt.subplots(figsize=(3.5, 1.7), layout='constrained') + + ax.plot(x, y, 'o', markersize=2, color='grey') + ax.tripcolor(x, y, z) + ax.tricontour(x, y, z, cmap='RdBu_r', linewidths=2) + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set(xlim=(-3, 3), ylim=(-3, 3)) + + plt.show() + + + .. grid-item-card:: + :padding: 2 + + .. toctree:: + :maxdepth: 2 + :includehidden: + + threed + + + .. grid-item-card:: + :padding: 2 + + + .. plot:: + :height: 7em + + import matplotlib.pyplot as plt + import numpy as np + + # Make data + X = np.arange(-5, 5, 0.25) + Y = np.arange(-5, 5, 0.25) + X, Y = np.meshgrid(X, Y) + R = np.sqrt(X**2 + Y**2) + Z = np.sin(R) + + # Plot the surface + fig, ax = plt.subplots(subplot_kw={"projection": "3d"}, + layout='constrained', figsize=(4*0.8, 2.7*0.8)) + ax.plot_surface(X, Y, Z, vmin=Z.min() * 2) + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_zlabel('z') diff --git a/galleries/users_explain/plotting/pairwise.py b/galleries/users_explain/plotting/pairwise.py new file mode 100644 index 000000000000..0bedcdfdcb78 --- /dev/null +++ b/galleries/users_explain/plotting/pairwise.py @@ -0,0 +1,337 @@ +""" +.. _plotting_pairwise: + +Pairwise data +============= + +The most common plot type is a simple y versus x plot. Typically we +will have arrays :math:`x_i` and :math:`y_i` of equal size that we want to plot +against each other. +""" + +import matplotlib.pyplot as plt +import numpy as np + +plt.rcParams['figure.constrained_layout.use'] = True +plt.rcParams['figure.figsize'] = (5, 4) + + +# %% +# +# plot +# ---- +# +# The most simple way to plot x and y data versus each other is to use the +# `~.Axes.plot` method. + +x = np.linspace(-2 * np.pi, 2 * np.pi, 30) +y = np.sinc(x) + +fig, ax = plt.subplots() +ax.plot(x, y) +ax.set_xlabel('x') +ax.set_ylabel('sinc(x)') + +# %% +# By default, `~.Axes.plot` joins data points with a solid straight line, as +# shown in the jagged nature of the plot above. We can style that line, +# with dashes, plot the data with symbols, or both styles, as demonstrated below. + +fig, axs = plt.subplots(3, 1, sharex=True) +ax = axs[0] +ax.plot(x, y, '--') +ax.set_ylabel('sinc(x)') +ax = axs[1] +ax.plot(x, y, 'd') +ax = axs[2] +ax.plot(x, y, 'd--') +ax.set_xlabel('x') + +# %% +# Multiple datasets can be plotted simultaneously against a single ``x`` array +# if the shape of ``Y`` is compatible. In this example, ``Y`` has the shape ``(30, 3)``, +# meaning each column has the same length as ``x``. +# Each column in ``Y`` is assigned a different color according to the +# default :ref:`color cycle `. A legend for each column in +# ``Y`` is generated by providing a **label** with a list of column names: + +Y = np.arange(30*3).reshape(3, 30).T +fig, ax = plt.subplots(figsize=(5, 3)) +ax.plot(x, Y, label=['column 1', 'column 2', 'column 3']) +ax.legend() +ax.set_xlabel('x') + +# %% +# fill_between, fill_betweenx, and stackplot +# ----------------------------------------- +# +# The `~.Axes.fill_between` method is useful to indicate a confidence interval +# around a line plot. In this example, the confidence interval is imagined to +# grow with distance in the x direction from the origin, but typically this +# would be based on data. `~.Axes.fill_betweenx` does the same thing but for +# the y direction. + +fig, axs = plt.subplots(1, 2) +ax = axs[0] +ax.plot(x, y) +ax.set_title("fill_between") +ax.fill_between(x, y - np.abs(x) / 20, y + np.abs(x) / 20, color='C0', alpha=0.5) +ax.set_ylabel('x') +ax.set_xlabel('sinc(x)') + +ax = axs[1] +ax.plot(y, x) +ax.set_title("fill_betweenx") +ax.fill_betweenx(x, y - np.abs(x) / 20, y + np.abs(x) / 20, color='C0', alpha=0.5) +ax.set_ylabel('y') +ax.set_xlabel('sinc(y)') + +# %% +# `~.Axes.fill_between` can also be used to fill between two lines, and can +# have conditions set on when to fill. Here we fill between two lines where +# the condition is met that the line with the larger y value is above the line +# with the smaller y value. The *where* keyword is used to set this condition. +# The *interpolate* keyword is used to linearly interpolate the fill to +# where the condition is just met. +# + +fig, ax = plt.subplots() +ax.plot(x, y, label='sinc(x)') +y2 = 2.0 * np.sinc(x + 0.3) +ax.plot(x, y2, label='2.0 sinc(x + 0.3)') +ax.fill_between(x, y, y2, where=(y >= y2), color='C0', alpha=0.3, interpolate=True) +ax.fill_between(x, y, y2, where=(y < y2), color='C1', alpha=0.3, interpolate=True) +ax.legend() +ax.set_xlabel('x') +ax.set_ylabel('sinc(x)') +ax.set_title("fill_between with condition") + +# %% +# .. seealso:: +# :ref:`fill_between_demo` for more `~.Axes.fill_between` examples. +# +# `~.Axes.stackplot` is useful for plotting series of data that stack on top of +# each other, often when the data represents a sum of different components. +# Here we plot three series of data and then that we then sum them up in the stackplot. + +fig, axs = plt.subplots(2, 1) +rng = np.random.default_rng(seed=19680801) + +data = rng.random(size=(30, 3)) +x = np.arange(30) +ax = axs[0] +ax.plot(x, data, label=['A', 'B', 'C']) +ax.legend() +ax.set_ylabel('data') +ax = axs[1] +ax.stackplot(x, data.cumsum(axis=1).T, labels=['A', 'A+B', 'A+B+C'], alpha=0.8) +ax.legend() +ax.set_xlabel('x') +ax.set_ylabel('stacked data') +ax.set_title("stackplot") + +# %% +# errorbar +# -------- +# +# Confidence intervals in both x and y can be shown using the `~.Axes.errorbar` method. +# The `~.Axes.errorbar` method has many options to control the appearance of the plot. +# The error bars can be specified as a scalar or as an array for each data point. + +x = np.linspace(0, 10, 50) +dy = 0.8 +y = np.sin(x) + dy * np.random.randn(50) +errx = 0.2 + np.random.rand(50) / 3 +erry = 0.2 + np.random.rand(50) / 3 + +fig, ax = plt.subplots() +ax.errorbar(x, y, xerr=errx, yerr=erry, fmt='o') + +ax.set_title("errorbar") +ax.set_xlabel("x") +ax.set_ylabel("sin(x) plus noise") + +# %% +# +# `~.Axes.errorbar` inherits from `~.Axes.plot`, allowing the use of the same +# format to control the marker's appearance. The appearance of error bars is +# controlled by keyword arguments such as *ecolor* for the color of the error +# bar lines, **capsize** for the length of the error bar caps, and *elinewidth* +# for the thickness of the error bar lines. Error bars can also be asymmetric +# if *yerr* or *xerr* are provided as 2D arrays. + +fig, ax = plt.subplots() +ax.errorbar(x, y, yerr=[erry, 2*erry], xerr=[errx, 2*errx], fmt='o', + ecolor='lightgray', elinewidth=2, capsize=5) +ax.set_title("Asymmetric error bars") +ax.set_xlabel("x") +ax.set_ylabel("sin(x) plus noise") +# %% +# +# scatter +# ------- +# +# The `~.Axes.scatter` method is similar to `~.Axes.plot` in that it plots two +# arrays of data against each other, but differs in the following ways: +# +# * there is no option to connect markers with lines, +# * the size and color of markers can vary according to the values of other data arrays. +# +# This example demonstrates how to create a scatter plot with varying point sizes using +# the *s* keyword and and colors using the *c* keyword. + +y = np.sin(x) + +sizes = np.linspace(20, 200, len(x)) # Varying point sizes +colors = y # Use y-values to map to color + +fig, ax = plt.subplots() +scatter = ax.scatter(x, y, c=colors, s=sizes, cmap='viridis', alpha=0.6, + edgecolor='black') +ax.set_title("Scatter Plot using scatter()") +ax.set_xlabel("x") +ax.set_ylabel("sin(x)") +fig.colorbar(scatter, label="Value of sin(x)") + +####################################################################################### +# The marker style can be changed (see :mod:`matplotlib.markers` for a full +# list), but each call to `~.Axes.scatter` can only accept one *marker* type. +# To code data by different marker shapes, make multiple calls to +# `~.Axes.scatter`. + +y2 = np.cos(x) +colors2 = y2 + +fig, ax = plt.subplots() +# Two scatter calls, one for each data set: +scatter = ax.scatter(x, y, c=colors, s=36, cmap='YlGn_r', alpha=0.6, + edgecolor='black', label='sin(x)') +scatter2 = ax.scatter(x, y2, marker='d', c=colors2, s=36, cmap='RdBu_r', + alpha=0.6, edgecolor='black', label='cos(x)') + +ax.set_title("Coding by marker type") +ax.set_xlabel("x") +ax.set_facecolor('0.8') +ax.legend(fontsize='small') +ax.set_ylabel("sin(x), cos(x)") + +# add some colorbars below plot +cax1 = ax.inset_axes([0.05, -0.25, 0.4, 0.05]) +fig.colorbar(scatter2, cax=cax1, label="Value of cos(x)", location='bottom') +cax2 = ax.inset_axes([0.55, -0.25, 0.4, 0.05]) +fig.colorbar(scatter, cax=cax2, label="Value of sin(x)", location='bottom') + + +# %% +# bar and stem +# ------------ +# +# `~.Axes.bar`, `~.Axes.stairs`, and `~.Axes.stem` are useful for plotting data +# that deviates from a zero or mean value. These methods are often used to plot +# histograms. + +x = x[::2] +y = y[::2] +fig, axs = plt.subplots(1, 2, sharex=True, sharey=True) + +ax = axs[0] +# need to specify a width so the bars don't overlap. +ax.bar(x, y, width=0.8*np.median(np.diff(x))) +ax.set_title("bar") +ax.set_xlabel('x') + +ax = axs[1] +ax.stem(x, y) +ax.set_title("stem") +ax.set_xlabel('x') +ax.set_ylabel('sin(x)') + +# %% +# `~.Axes.bar` does not automatically calculate the *width* of the bars, so it +# typically needs to be calculated manually to achieve the correct spacing. The *width* +# can also be specified as an array with the same length as *x* to set the width of each +# bar individually. + +fig, ax = plt.subplots() +width = np.concatenate(([np.diff(x)[0]], np.diff(x))) +ax.bar(x, y, width=width * 0.8) +ax.set_title("bar with widths") + +# %% +# step and stairs +# --------------- +# +# `~.Axes.step` and `~.Axes.stairs` are similar to `~.Axes.plot` but plot a +# step between each data point. They accept differently shaped data depending +# on the use case. +# +# `~.Axes.step` particularly useful as it accepts the same data shape as +# `~.Axes.plot`. + +fig, ax = plt.subplots() + +ax.plot(x, y, '-o', color='gray', alpha=0.5) +ax.step(x, y) +ax.set_ylabel('sin(x)') +ax.set_title('step') + +# %% + +# The steps can be centered on the data in different ways using the **where** +# keyword. The default is **where='pre'**, which means the step extends to the +# left of the data point. **where='mid'** means the step extends halfway to the +# next data point, and **where='post'** means the step extends to the right of +# the data point: + +fig, axs = plt.subplots(3, 1, sharex=True, sharey=True, figsize=(4.5, 5)) + +todo = ['pre', 'mid', 'post'] +for ax, where in zip(axs, todo): + ax.plot(x, y, '-o', color='gray', alpha=0.5) + ax.step(x, y, where=where) + ax.set_title(f'step where={where}') + +# %% +# .. seealso:: +# :ref:`step_demo` for more step examples. + +# %% +# +# `~.Axes.stairs` is useful for plotting histograms, and specifies the edges of +# steps rather than the centers, so can directly be used with the result from +# `~numpy.histogram`. + +data = rng.normal(size=1000) +hist, bin_edges = np.histogram(data, bins=np.arange(-4, 4, 0.2), density=True) + +data2 = rng.uniform(low=-4, high=4, size=300) +hist2, bin_edges2 = np.histogram(data2, bins=np.arange(-4, 4, 0.4), density=True) + +fig, ax = plt.subplots() +ax.stairs(hist, bin_edges, fill=True, alpha=0.4, orientation='vertical', + label='normal') + +ax.stairs(hist2, bin_edges2, fill=True, alpha=0.4, orientation='vertical', + label='uniform') +ax.set_title('stairs from histogram') +ax.set_xlabel('data') +ax.set_ylabel('probability density function') +ax.legend() + +# %% +# .. admonition:: References +# +# The use of the following functions, methods, classes and modules is shown +# in this example: +# +# - `matplotlib.axes.Axes.plot` / `matplotlib.pyplot.plot` +# - `matplotlib.axes.Axes.fill_between` / `matplotlib.pyplot.fill_between` +# - `matplotlib.axes.Axes.fill_betweenx` / `matplotlib.pyplot.fill_betweenx` +# - `matplotlib.axes.Axes.stackplot` / `matplotlib.pyplot.stackplot` +# - `matplotlib.axes.Axes.errorbar` / `matplotlib.pyplot.errorbar` +# - `matplotlib.axes.Axes.scatter` / `matplotlib.pyplot.scatter` +# - `matplotlib.axes.Axes.bar` / `matplotlib.pyplot.bar` +# - `matplotlib.axes.Axes.stem` / `matplotlib.pyplot.stem` +# - `matplotlib.axes.Axes.step` / `matplotlib.pyplot.step` +# - `matplotlib.axes.Axes.stairs` / `matplotlib.pyplot.stairs` +# - `matplotlib.figure.Figure.colorbar` diff --git a/galleries/users_explain/plotting/statistical.py b/galleries/users_explain/plotting/statistical.py new file mode 100644 index 000000000000..259aeb38cdaf --- /dev/null +++ b/galleries/users_explain/plotting/statistical.py @@ -0,0 +1,281 @@ +""" + +Statistical plots +================= + +Matplotlib has a few of the most common statistical plots built in, such as +histograms, boxplots, and violin plots. These methods take data, compute +statistics, and then visualize the statistics. When possible, these functions +will automatically calculate the statistics for you, such as binning and +aggregating the data for histograms, or quartiles and outliers for boxplots. +Statistical computation is usually done by underlying `numpy` methods. + +""" + +# %% +# hist +# ---- +# +# The `~.axes.Axes.hist` method is used to plot a histogram. The data is +# binned and the frequency of each bin is plotted. The default number of bins +# is 10, but this can be adjusted with the *bins* keyword. + +import matplotlib.pyplot as plt +import numpy as np + +plt.rcParams['figure.constrained_layout.use'] = True +plt.rcParams['figure.figsize'] = (5, 4) + +rng = np.random.default_rng(19680801) +# collect samples from the normal distribution" +data = rng.standard_normal(1000) + +fig, axs = plt.subplots(2, 1) +ax = axs[0] +ax.plot(data, '.') +ax.set_title('data') +ax.set_ylabel('data values') +ax.set_xlabel('sample number') +ax = axs[1] +ax.hist(data, bins=30) +ax.set_title('histogram of the data') +ax.set_xlabel('data values') +ax.set_ylabel('frequency') + +# %% +# Sometime it is useful to normalize the histogram so that the total area under +# the histogram is 1. This is known as a probability density function (pdf). +# The *density* argument to `~.axes.Axes.hist` can be set to ``True`` to +# normalize the histogram. The total area of the histogram will sum to 1. + +fig, ax = plt.subplots() +ax.hist(data, bins=30, density=True) +ax.set_title('normalized histogram of the data') +ax.set_xlabel('data values') +ax.set_ylabel('probability density') + +# %% +# Other normalizations are possible using the *weights* argument. See +# :ref:`histogram_normalization` for more details. +# +# It is possible to plot multiple histograms in the same figure by passing +# a 2D array to ``hist``. The columns of the array are the data values for +# each histogram. + +# make three sets of data, with each set in a column of the array: +data = rng.standard_normal((1000, 3)) + +fig, ax = plt.subplots() +ax.hist(data, bins=30, density=True, label=['set1', 'set2', 'set3']) +ax.legend(fontsize='small') +ax.set_title('multiple histograms') +ax.set_xlabel('data values') +ax.set_ylabel('probability density') + +# %% +# .. seealso:: +# +# There are many styling and processing options for histograms. For details, +# see: +# +# - :ref:`histogram_normalization` +# - :ref:`histogram_histtypes` +# - :ref:`histogram_multihist` + + +# %% +# hist2d and hexbin +# ----------------- +# +# If the data has two coordinates, eg arrays of :math:`(x_i, y_i)` pairs, you +# can use the `~.axes.Axes.hist2d` or `~.axes.Axes.hexbin` methods to visualize +# the frequency that the data occurs in a 2D space. + +# make data: correlated + noise +x = rng.normal(size=5000) +y = 1.2 * x + rng.normal(size=5000) / 2 + +# plot: +fig, axs = plt.subplots(2, 1, figsize=(5, 7), sharex=True, sharey=True) +ax = axs[0] +ax.plot(x, y, '.', alpha=0.5, markeredgecolor='none') +ax.set_title('data') +ax.set_ylabel('y') + +ax = axs[1] +bins = (np.arange(-3, 3.1, 0.2), np.arange(-3, 3.1, 0.2)) +N, xbins, ybin, pc = ax.hist2d(x, y, bins=bins, vmax=30, cmap='plasma') +ax.contour(xbins[1:], ybin[1:], N.T, levels=4, colors='c', alpha=0.7) +ax.set_ylabel('y') +ax.set_xlabel('x') + +ax.set(xlim=(-3, 3), ylim=(-3, 3)) +fig.colorbar(pc, ax=ax, label='counts') + +# %% +# Note that `~.axes.Axes.hist2d` returns the histogram values ``N`` above, but +# does so transposed from the typical Matplotlib convention. We have used this +# transposed form to plot the contours of the density over the two-dimensional +# histogram. +# +# The *density* argument to `~.axes.Axes.hist2d` can be set to ``True`` to plot +# a normalized 2D histogram. Again the normalization is such that the area +# integral of the histogram is one. Like with `~.axes.Axes.hist`, other +# normalizations are possible using the *weights* argument. + +fig, axs = plt.subplots(2, 1, figsize=(5, 7), sharex=True, sharey=True) +ax = axs[0] +ax.plot(x, y, '.', alpha=0.5, markeredgecolor='none') +ax.set_title('data') +ax.set_ylabel('y') + +ax = axs[1] +bins = (np.arange(-3, 3.1, 0.2), np.arange(-3, 3.1, 0.2)) +N, xbins, ybin, pc = ax.hist2d(x, y, bins=bins, density=True, cmap='plasma') +ax.set_ylabel('y') +ax.set_xlabel('x') + +ax.set(xlim=(-3, 3), ylim=(-3, 3)) +fig.colorbar(pc, ax=ax, label='Probability density') + +# %% +# The `~.axes.Axes.hexbin` method is similar to `~.axes.Axes.hist2d`, but uses +# hexagonal bins instead of rectangular bins. This can be useful when the data +# is sparse or the distribution is uneven. The hexagonal bins are arranged in +# a hexagonal lattice, and the density of data in each hexagon is computed. + +fig, ax = plt.subplots() + +ax.hexbin(x, y, cmap='plasma', gridsize=20) +ax.set_ylabel('y') +ax.set_xlabel('x') +ax.set_title('hexbin plot') + +ax.set(xlim=(-3, 3), ylim=(-3, 3)) + +# %% +# .. seealso:: +# +# - :ref:`hexbin_demo` +# +# boxplot and violinplot +# ---------------------- +# +# The `~.axes.Axes.boxplot` and `~.axes.Axes.violinplot` methods are used to +# visualize the distribution of data in discrete bins. If :math:`X_{ij}` is +# the data set, the statistics are calculated for each column in +# :math:`X_{ij}`, and a box or violin is drawn for each column. +# +# The boxplot usually shows the quartiles of the data distribution in each +# column, and is typically used to see if data sets are statistically distinct. +# A violin plot is similar to a boxplot, but shows the density of the data at +# different values. The width of the violin is proportional to the density of +# the data at that value, using a smoothed `kernel density estimation +# `_ of the # +# underlying distribution. +# +# Below, we compare the data plotted as dots with a degree of transparency to +# give a feel for the raw data in each column. A histogram of all three data +# sets is also shown, demonstrating the distribution of the data. The boxplot +# and violin plot are then shown for the same data. By default, +# `~.axes.Axes.boxplot` shows the median, quartiles, and outliers, while +# `~.axes.Axes.violinplot` shows a kernel density estimate of the data. + +# make three categories of data +data = np.zeros((100, 3)) +data[:, 0] = rng.normal(loc=0, scale=1, size=100) +data[:, 1] = rng.normal(loc=1.1, scale=1.5, size=100) +data[:, 2] = rng.normal(loc=-1.5, scale=0.7, size=100) + +fig, axs = plt.subplot_mosaic([['plot', 'hist'], ['box', 'violin']], figsize=(5, 5)) + +ax = axs['plot'] +for i in range(3): + ax.plot(i + 1 + 0 * data[:, i], data[:, i], '.', label=f'col. {i}', alpha=0.2, + markeredgecolor='none') +ax.set_xlabel('column number') +ax.set_ylabel('data values') +ax.set_title('plot of data') +ax.set_xlim(0.5, 3.5) + +ax = axs['hist'] +ax.hist(data, bins=np.arange(-4, 4.1, 0.25), density=True, + label=['column 0', 'column 1', 'column 2'], histtype='step', + orientation='horizontal') +ax.set_ylabel('data values') +ax.set_xlabel('probability density') +ax.legend(fontsize='small') +ax.set_title('histograms') + +ax = axs['box'] +ax.boxplot(data) +ax.set_xlabel('column number') +ax.set_ylabel('data values') +ax.set_title('boxplot') + +ax = axs['violin'] +ax.violinplot(data) +ax.set_xlabel('column number') +ax.set_ylabel('data values') +ax.set_title('violin plot') + +# %% +# +# `~.axes.Axes.boxplot` and `~.axes.Axes.violinplot` can be customized in many +# ways. For example, the *showmeans*, *showmedians*, *showextrema*, and +# *showcaps* arguments can be used to show or hide the mean, median, extrema, +# and caps. The *vert* argument can be used to make the boxplot horizontal, +# and the *positions* argument can be used to set the positions of the boxes. +# The *widths* argument can be used to set the width of the boxes. +# +# .. seealso:: +# +# - :ref:`boxplot_demo` +# - :ref:`boxplot_color` +# - :ref:`boxplot_artists` +# - :ref:`boxplot_vs_violin` +# - :ref:`violinplot` +# - :ref:`customized_violin` +# +# eventplot +# --------- +# +# An `~.axes.Axes.eventplot` draws a vertical line at every data point in a 1D +# array, :math:`x_i`, often to compare even timing. Usually the events are +# passed into the method as a sequence of 1D arrays because the events being +# timed usually have a different number of occurrences. +# +# Note in the below, we can label the events by making *lineoffsets* a list of +# strings. This will make the y-axis a :ref:`categorical +# ` axis, with the labels given in the list. + +# make some data + +len = [100, 75] +dataA = np.cumsum(rng.rayleigh(scale=0.1, size=30)) +dataB = np.cumsum(rng.rayleigh(scale=0.1 * 3 / 2, size=20)) +data = [dataA, dataB] + +fig, ax = plt.subplots() +ax.eventplot(data, orientation='horizontal', linelengths=0.9, + color=['C0', 'C1'], lineoffsets=['data A', 'data B']) + +ax.set_xlabel('time') +ax.set_ylabel('event type') + +# %% +# .. seealso:: +# - :ref:`eventplot_demo` +# +# .. admonition:: References +# +# The use of the following functions, methods, classes and modules is shown +# in this example: +# +# - `matplotlib.axes.Axes.hist` / `matplotlib.pyplot.hist` +# - `matplotlib.axes.Axes.hist2d` / `matplotlib.pyplot.hist2d` +# - `matplotlib.axes.Axes.hexbin` / `matplotlib.pyplot.hexbin` +# - `matplotlib.axes.Axes.boxplot` / `matplotlib.pyplot.boxplot` +# - `matplotlib.axes.Axes.violinplot` / `matplotlib.pyplot.violinplot` +# - `matplotlib.axes.Axes.eventplot` / `matplotlib.pyplot.eventplot` +# - `matplotlib.axes.Axes.plot` / `matplotlib.pyplot.plot` diff --git a/galleries/users_explain/plotting/threed.py b/galleries/users_explain/plotting/threed.py new file mode 100644 index 000000000000..63b74788d46e --- /dev/null +++ b/galleries/users_explain/plotting/threed.py @@ -0,0 +1,249 @@ +""" +.. _plotting_threed: + +3D and volumetric data +====================== + +Matplotlib has support for three-dimensional plots, including surface plots, +wireframes, and 3D scatter plots. + +Note, however, that Matplotlib does not do proper ray-tracing, and hence +multiple surfaces in one visualization will not occlude one another correctly; +the last surface drawn will cover previous surfaces, regardless of their +distance from the viewer. Either try to combine surfaces into one (which is +possible for simple plots, see :ref:`intersecting_planes` and :ref:`box3d`), or +for true 3D, consider using `Mayavi +`_. + +Plotting in 3D can be done using the `.mpl_toolkits.mplot3d` toolkit by +declaring an axes is three dimensional, instead of the default two-dimensional. +After that, most of the methods are the same as their two-dimensional +counterparts, except a third array is added to represent the data along the +z-axis. +""" + +# %% +# plot and scatter +# ---------------- +# +# The most basic 3D plot is a line or collection of scatter plot created from +# sets of (x, y, z) triples. In analogy with the more common 2D plots, the +# 3D plots are simple to create. We use the *subplot_kw* argument to create a +# 3D projection for the plot. + +import matplotlib.pyplot as plt +import numpy as np + +plt.rcParams['figure.figsize'] = (5, 4) + +# make data +n = 100 +xs = np.linspace(0, 1, n) +ys = np.sin(xs * 6 * np.pi) +zs = np.cos(xs * 6 * np.pi) + +# Make an axes with a 3d projection +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + +# plot +ax.plot(xs, ys, zs) + +# label +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_zlabel('z') +ax.set_title('3d plot') + + +# %% +# For 3D plots, it is possible to rotate the plot by clicking and dragging in +# an interactive backend. For a static backend, the view can be changed by +# setting the elevation and azimuth angles. The elevation is the angle above +# the x-y plane, and the azimuth is the rotation around the z-axis. The +# default view is elevation of 30 degrees and an azimuth of -60 degrees. The +# azimuth is zero looking along the positive x-axis at the y-z plane, and if +# elevation is positive, then increasing azimuth rotates the view in a +# clockwise direction. + +# Make an axes with a 3d projection +fig, axs = plt.subplots(2, 3, figsize=(8.5, 6.5), subplot_kw={"projection": "3d"}) + +for nn, ax in enumerate(axs.flat): + + # change the view + ax.view_init(elev=30, azim=((-60 + nn*20))) + + ax.plot([0, 1], [0, 0], -1, 'r') + ax.plot([1], [0], -1, 'dr') + ax.plot(xs, ys, zs) + ax.plot(xs[0], ys[0], zs[0], 'go') + ax.plot(xs[-1], ys[-1], zs[-1], 'ro') + + ax.set_title(f'view_init(30, {(-60 + nn*20)})') + + # label + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_zlabel('z') + +# %% +# We can also create a 3D scatter plot, analogous to a 2D scatter plot, by +# passing arrays of x, y, and z coordinates to the *scatter* method, and +# specifying *c* and *s* to set the color and size of the +# points, if desired. Here we set the color to be the same as the x value, and +# the size as the absolute value of the z value. + +# make data +c = xs +s = np.abs(zs) * 100 + +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) +sc = ax.scatter(xs, ys, zs, c=c, s=s) +# label +fig.colorbar(sc, ax=ax, location='left', shrink=0.4) +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_zlabel('z') + +# %% +# plot_wireframe, plot_surface +# ---------------------------- +# +# The `~.Axes3D.plot_wireframe` method can be used to plot a wireframe +# version of a surface. Wireframe spacing is set by the underlying data, but +# can be adjusted by setting the *rstride* (row-stride) and *cstride* +# (column-stride) of the plot if needed. + +X = np.arange(-5, 5, 0.25) +Y = np.arange(-5, 5, 0.25) +X, Y = np.meshgrid(X, Y) +R = np.sqrt(X**2 + Y**2) +Z = np.sin(R) + +fig, axs = plt.subplots(1, 2, figsize=(6, 3.5), subplot_kw={"projection": "3d"}) +axs[0].plot_wireframe(X, Y, Z) +axs[0].set_title('plot_wireframe') + +axs[1].plot_wireframe(X, Y, Z, rstride=3, cstride=3, color='C2') +axs[1].set_title('rstride=3, cstride=3') + +# %% +# The `.Axes3D.plot_surface` method can be used in the same way to plot a +# surface plot. If the colormap is not specified then the surface is colored +# with one color, but shading is applied to the surface to give it a 3D +# appearance. If a colormap via the *cmap* keyword is specified then the +# surface will be colored by the Z value of the surface. It is possible to +# shade a color-mapped surface by passing the rgba values of the surface colors +# via the *facecolors* keyword (see :ref:`custom_shaded_3d_surface` for +# details). + +fig, axs = plt.subplots(1, 2, figsize=(6, 3.5), subplot_kw={"projection": "3d"}) +axs[0].plot_surface(X, Y, Z) +axs[0].set_title('plot_surface') + +axs[1].plot_surface(X, Y, Z, cmap='viridis') +axs[1].set_title('cmap="viridis"') + + +# %% +# .. seealso:: +# - :ref:`surface3d` +# - :ref:`surface3d_2` +# - :ref:`surface3d_3` +# + +# The `~mpl_toolkits.mplot3d.axes3d.Axes3D.plot_trisurf` method can be used +# just like `~.axes.Axes.tripcolor` when the x and y data is not on a Cartesian +# grid. It makes a triangulation in x and y and plots the surface in 3D. + +rng = np.random.default_rng(19680801) +x = rng.uniform(-5, 5, size=128) +y = rng.uniform(-5, 5, size=128) +r = np.sqrt(x**2 + y**2) +z = np.sin(r) + +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) + +ax.plot_trisurf(x, y, z) +ax.set_title('plot_trisurf') + +# %% +# +# .. seealso:: +# - :ref:`trisurf3d` +# - :ref:`trisurf3d_2` +# +# stem and bar3d +# -------------- +# +# The `~mpl_toolkits.mplot3d.axes3d.Axes3D.bar3d` and +# `~mpl_toolkits.mplot3d.axes3d.Axes3D.stem` methods can give an idea of +# two-dimensional data counts, similar to `~.axes.Axes.hist2d`. So for +# instance if we histogram a random array of data: + +x = rng.normal(size=5000) +y = rng.normal(size=5000) + +H, xedges, yedges, = np.histogram2d(x, y, bins=10) +X, Y = np.meshgrid(xedges[:-1], yedges[:-1]) + +X = X.flatten() +Y = Y.flatten() +H = H.flatten() + + +fig, axs = plt.subplots(1, 2, figsize=(8, 4), subplot_kw={"projection": "3d"}) + +axs[0].bar3d(X, Y, np.zeros_like(X), + dx=0.2 * np.ones_like(X), dy=0.2 * np.ones_like(X), + dz=H.flatten(), shade=True) + +axs[0].set_title('bar3d') + +axs[1].stem(X.flat, Y.flat, H.flatten()) +axs[1].set_title('stem') + +# %% +# +# .. seealso:: +# - :ref:`bars3d` +# - :ref:`stem3d_demo` +# +# quiver +# ------ +# +# There is a three-dimensional `.Axes3D.quiver` equivalent of +# `~.axes.Axes.quiver` that is called the same way, but with a third array for +# the z direction. Here we plot a 3D field of arrows: + +# Make data +n = 4 +x = np.linspace(-1, 1, n) +y = np.linspace(-1, 1, n) +z = np.linspace(-1, 1, n) +X, Y, Z = np.meshgrid(x, y, z) +U = (X + Y)/5 +V = (Y - X)/5 +W = Z*0 + +# Plot +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) +ax.quiver(X, Y, Z, U, V, W) + +# %% +# .. seealso:: +# - :ref:`quiver3d` +# +# .. admonition:: References +# +# The use of the following functions, methods, classes and modules is shown +# in this document: +# +# - `.Axes3D.plot` +# - `.Axes3D.scatter` +# - `.Axes3D.plot_wireframe` +# - `.Axes3D.plot_surface` +# - `.Axes3D.plot_trisurf` +# - `.Axes3D.bar3d` +# - `.Axes3D.stem` +# - `.Axes3D.quiver` diff --git a/galleries/users_explain/plotting/unstructuredgrid.py b/galleries/users_explain/plotting/unstructuredgrid.py new file mode 100644 index 000000000000..ce23944b8854 --- /dev/null +++ b/galleries/users_explain/plotting/unstructuredgrid.py @@ -0,0 +1,123 @@ +""" +.. _plot_unstructuredgrid: + +Unstructured data +================= + +Unlike :ref:`structured grids `, three-dimensional data is often +collected without the benefit of a grid, with :math:`z = f(x, y)` where +:math:`x` and :math:`y` are one-dimensional arrays of the same length, and +hence :math:`z` is also one-dimensional. Sometimes it is useful to grid that +data via appropriate interpolation schemes (see `scipy.interpolate.griddata` +for some in python). However, if the data is spaced appropriately, it can sometimes +be plotted directly in Matplotlib. + +Matplotlib accomplishes this via a suite of triangulation routines in the +:mod:`matplotlib.tri` module. The most basic triangulation routine is +`~matplotlib.tri.Triangulation`, which is a simple wrapper around the popular +`Qhull `_ library. The `~matplotlib.tri.Triangulation` +class is used to create a triangulation of a set of points, and this +triangulation can then be used to create either faceted psuedocolor plots, or +contour plots. + +""" + +# %% +# triplot +# ------- +# +# The most basic plot is the `~.axes.Axes.triplot` method, which plots the +# edges of triangles in a triangulation. Here we create a simple triangulation +# on a set of points, and plot the edges of the triangles that are created. + +import matplotlib.pyplot as plt +import numpy as np + +plt.rcParams['figure.constrained_layout.use'] = True +plt.rcParams['figure.figsize'] = (5, 4) + +# make data: +np.random.seed(19680801) +x = np.random.uniform(-3, 3, 256) +y = np.random.uniform(-3, 3, 256) +z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2) + +fig, ax = plt.subplots() + +# plot the points: +ax.plot(x, y, 'm.') + +# plot the triangulation: +ax.triplot(x, y) + +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_title('triplot') + +# %% +# In advanced usage, one could pass a `~matplotlib.tri.Triangulation` object to +# the `~.axes.Axes.triplot` method. See :ref:`triplot_demo` for more details. +# +# tripcolor +# --------- +# +# The `~.axes.Axes.tripcolor` method can be used to plot a surface by coloring +# each triangle based on the value of a colormap. Here we plot the same +# triangulation as above, but color the triangles based on the values of +# :math:`z` on the corners. The default shading is "flat", which averages the +# values of :math:`z` on each triangle, but `~.axes.Axes.tripcolor` can also perform +# Gouraud shading for a smoother appearance. + +fig, axs = plt.subplots(2, 1, figsize=(5, 7)) +for ax, shade in zip(axs, ['flat', 'gouraud']): + ax.plot(x, y, 'm.') + pc = ax.tripcolor(x, y, z, cmap='RdBu_r', vmin=-1, vmax=1, shading=shade) + fig.colorbar(pc, ax=ax, label='z') + ax.set_title(f'tripcolor shading = "{shade}"') + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_facecolor('lightgray') + +# %% +# It is also possible to set the values on the face of each triangle, but this +# is better done if you have a `~matplotlib.tri.Triangulation` object rather +# than the raw x, y, z arrays. See :ref:`tripcolor_demo` for more details. +# +# tricontour and tricontourf +# -------------------------- +# +# The `~.axes.Axes.tricontour` and `~.axes.Axes.tricontourf` methods can be +# used to plot contours of unstractured data, where the underlying +# triangulation is used to interpolate the contour locations. Here we plot +# contours of the same data as above. + +fig, ax = plt.subplots() +ax.plot(x, y, 'm.') +pc = ax.tricontourf(x, y, z, cmap='RdBu_r', vmin=-1, vmax=1, levels=15) +fig.colorbar(pc, ax=ax, label='z') + +ax.set_xlabel('x') +ax.set_ylabel('y') +ax.set_facecolor('lightgray') + +# %% +# As with `~.axes.Axes.tripcolor`, a `~matplotlib.tri.Triangulation` object can be +# passed instead of the raw x and y arrays. +# +# .. seealso:: +# For more advanced use of `~.axes.Axes.tricontour` and +# `~.axes.Axes.tricontourf`, see: +# +# - :ref:`tricontour_demo` +# - :ref:`tricontour_smooth_user` +# - :ref:`tricontour_smooth_delaunay` +# +# .. admonition:: References +# +# The use of the following functions, methods, classes and modules is shown +# in this example: +# +# - `matplotlib.axes.Axes.triplot` / `matplotlib.pyplot.triplot` +# - `matplotlib.axes.Axes.tripcolor` / `matplotlib.pyplot.tripcolor` +# - `matplotlib.axes.Axes.tricontour` / `matplotlib.pyplot.tricontour` +# - `matplotlib.axes.Axes.tricontourf` / `matplotlib.pyplot.tricontourf`