File: cmap.py

package info (click to toggle)
python-pyvista 0.44.1-11
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 159,804 kB
  • sloc: python: 72,164; sh: 118; makefile: 68
file content (147 lines) | stat: -rw-r--r-- 4,372 bytes parent folder | download
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
.. _colormap_example:

Colormap Choices
~~~~~~~~~~~~~~~~

Use a Matplotlib, Colorcet, cmocean, or custom colormap when plotting scalar
values.
"""

from __future__ import annotations

from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import numpy as np

import pyvista as pv
from pyvista import examples

# %%
# Any colormap built for ``matplotlib``, ``colorcet``, or ``cmocean`` is fully
# compatible with PyVista. Colormaps are typically specified by passing the
# string name of the colormap to the plotting routine via the ``cmap``
# argument.
#
# See `Matplotlib's complete list of available colormaps`_,
# `Colorcet's complete list`_, and `cmocean's complete list`_.
#
# .. _Matplotlib's complete list of available colormaps: https://matplotlib.org/tutorials/colors/colormaps.html
# .. _Colorcet's complete list: https://colorcet.holoviz.org/user_guide/index.html
# .. _cmocean's complete list: https://matplotlib.org/cmocean/

# %%
# Custom Made Colormaps
# +++++++++++++++++++++
#
# To get started using a custom colormap, download some data with scalar values to
# plot.

mesh = examples.download_st_helens().warp_by_scalar()
# Add scalar array with range (0, 100) that correlates with elevation
mesh['values'] = pv.plotting.tools.normalize(mesh['Elevation']) * 100

# %%
# Build a custom colormap - here we make a colormap with 5 discrete colors
# and we specify the ranges where those colors fall:

# Define the colors we want to use
blue = np.array([12 / 256, 238 / 256, 246 / 256, 1.0])
black = np.array([11 / 256, 11 / 256, 11 / 256, 1.0])
grey = np.array([189 / 256, 189 / 256, 189 / 256, 1.0])
yellow = np.array([255 / 256, 247 / 256, 0 / 256, 1.0])
red = np.array([1.0, 0.0, 0.0, 1.0])

mapping = np.linspace(mesh['values'].min(), mesh['values'].max(), 256)
newcolors = np.empty((256, 4))
newcolors[mapping >= 80] = red
newcolors[mapping < 80] = grey
newcolors[mapping < 55] = yellow
newcolors[mapping < 30] = blue
newcolors[mapping < 1] = black

# Make the colormap from the listed colors
my_colormap = ListedColormap(newcolors)

# %%
# Simply pass the colormap to the plotting routine.
mesh.plot(scalars='values', cmap=my_colormap)

# %%
# Or you could make a simple colormap... any Matplotlib colormap can be passed
# to PyVista.
boring_cmap = plt.get_cmap("viridis", 5)
mesh.plot(scalars='values', cmap=boring_cmap)

# %%
# You can also pass a list of color strings to the color map.  This
# approach divides up the colormap into 5 equal parts.
mesh.plot(scalars=mesh['values'], cmap=['black', 'blue', 'yellow', 'grey', 'red'])

# %%
# If you still wish to have control of the separation of values, you
# can do this by creating a scalar array and passing that to the
# plotter along with the colormap
scalars = np.empty(mesh.n_points)
scalars[mesh['values'] >= 80] = 4  # red
scalars[mesh['values'] < 80] = 3  # grey
scalars[mesh['values'] < 55] = 2  # yellow
scalars[mesh['values'] < 30] = 1  # blue
scalars[mesh['values'] < 1] = 0  # black

mesh.plot(scalars=scalars, cmap=['black', 'blue', 'yellow', 'grey', 'red'])

# %%
# Matplotlib vs. Colorcet
# +++++++++++++++++++++++
#
# Let's compare Colorcet's perceptually uniform "fire" colormap to Matplotlib's
# "hot" colormap much like the example on the `first page of Colorcet's docs`_.
#
# .. _first page of Colorcet's docs: https://colorcet.holoviz.org/index.html
#
# The "hot" version washes out detail at the high end, as if the image is
# overexposed, while "fire" makes detail visible throughout the data range.
#
# Please note that in order to use Colorcet's colormaps including "fire", you
# must have Colorcet installed in your Python environment:
# ``pip install colorcet``

p = pv.Plotter(shape=(2, 2), border=False)
p.subplot(0, 0)
p.add_mesh(
    mesh,
    scalars='Elevation',
    cmap="fire",
    lighting=True,
    scalar_bar_args={'title': "Colorcet Fire"},
)

p.subplot(0, 1)
p.add_mesh(
    mesh,
    scalars='Elevation',
    cmap="fire",
    lighting=False,
    scalar_bar_args={'title': "Colorcet Fire (No Lighting)"},
)

p.subplot(1, 0)
p.add_mesh(
    mesh,
    scalars='Elevation',
    cmap="hot",
    lighting=True,
    scalar_bar_args={'title': "Matplotlib Hot"},
)

p.subplot(1, 1)
p.add_mesh(
    mesh,
    scalars='Elevation',
    cmap="hot",
    lighting=False,
    scalar_bar_args={'title': "Matplotlib Hot (No Lighting)"},
)

p.show()