简体   繁体   English

部分离散颜色图 matplotlib

[英]Partially discrete colormap matplotlib

While there are a number of examples of discrete colormap ( a , b , c ), I would like to do something a little different.虽然有许多离散颜色图( abc )的示例,但我想做一些不同的事情。 I want to have a 3D surface plot that has a sharp contrast between a small value and zero, so the colors 'jump' or the colormap is partially discrete.我想要一个 3D 曲面图,它在小值和零之间具有鲜明的对比,因此颜色“跳跃”或颜色图是部分离散的。 My reason for this is that I want to more clearly distinguish between small values and what is consider to be 'zero' within a plot.我这样做的原因是我想更清楚地区分小值和图中被认为是“零”的值。

I am generating a 3D surface plot and want to use a colormap (like 'terrain' ) to indicate height on the Z-axis.我正在生成一个 3D 曲面图,并希望使用颜色图(如'terrain' )来指示 Z 轴上的高度。 However, I want there to be a 'gap' in the colormap to highlight values that are sufficiently far from z=0 .但是,我希望颜色图中有一个“间隙”来突出显示离z=0足够远的值。 Specifically, let's say z<1e-6 is the bottom threshold of the colormap (eg, dark blue for terrain), but any value above that threshold to be in the middle of the colormap (eg green for terrain).具体来说,假设z<1e-6是颜色图的底部阈值(例如,地形的深蓝色),但高于该阈值的任何值都位于颜色图的中间(例如,地形的绿色)。

Below is a simple example and the corresponding output下面是一个简单的例子和​​相应的输出

import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt

y = np.linspace(-3, 3, 100)
x = np.linspace(-3, 3, 100)
z = np.zeros(shape=(x.shape[0], y.shape[0]))

for i in range(x.shape[0]):
    # creating some generic Z-axis data
    z[:, i] = norm.pdf(y, loc=0, scale=0.2+(i/100))
    z[:, i] = z[:, i] / np.sum(z[:, i])  # normalizing

z = np.where(z < 1e-6, 0, z)  # setting 'small enough' threshold

x_mat, y_mat = np.meshgrid(x, y)

f1 = plt.axes(projection='3d')
f1.plot_surface(x_mat, y_mat, z, cmap='terrain', edgecolor='none', rstride=1)
plt.show()

Here is what the output from above:这是上面的输出: 在此处输入图片说明

What I want the output to look like would be all the 'light blue' regions would instead be green.我希望输出看起来像所有“浅蓝色”区域而是绿色。 Once below the defined threshold ( 1e-6 here), the color would jump to dark blue (so no regions would be light blue).一旦低于定义的阈值(这里是1e-6 ),颜色就会跳到深蓝色(所以没有区域会是浅蓝色)。

Alright, I figured out a solution to my own problem.好吧,我想出了一个解决我自己问题的方法。 I adapted the solution from HERE to address my issue.我改编了这里的解决方案来解决我的问题。 Below is the code to accomplish this.下面是实现此目的的代码。

Setup:设置:

import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap

y = np.linspace(-3, 3, 100)
x = np.linspace(-3, 3, 100)
z = np.zeros(shape=(x.shape[0], y.shape[0]))

x_mat, y_mat = np.meshgrid(x, y)

# Threshold to apply
z_threshold = 1e-6


for i in range(x.shape[0]):
    z[:, i] = norm.pdf(y, loc=0, scale=0.2+(i/100))
    z[:, i] = z[:, i] / np.sum(z[:, i])  # normalizing

Next I define two different colormaps.接下来我定义两个不同的颜色图。 The first color map applies to all values above the threshold.第一个颜色图适用于高于阈值的所有值。 If values are below the threshold, it sets that square as transparent.如果值低于阈值,则将该方块设置为透明。

cmap = get_cmap('terrain')
# 1.8 and 0.2 are used to restrict the upper and lower parts of the colormap
colors = cmap((z - z_threshold) / ((np.max(z)*1.8) - (np.min(z))) + 0.2)
# if below threshold, set as transparent (alpha=0)
colors[z < z_threshold, -1] = 0

The second colormap defines the color for all places below the threshold.第二个颜色图定义阈值以下所有位置的颜色。 This step isn't fully necessary, but it does prevent the plane from being drawn below the rest of the plot.这一步不是完全必要的,但它确实可以防止平面绘制在图的其余部分下方。

colors2 = cmap(z)
colors2[z >= z_threshold, -1] = 0

Now the colormaps can be used in two 3D plot calls现在可以在两个 3D 绘图调用中使用颜色图

# init 3D plot
f1 = plt.axes(projection='3d')
# Plot values above the threshold
f1.plot_surface(x_mat, y_mat, z, facecolors=colors, edgecolor='none', rstride=1)
# Plot values below the threshold
z_below = np.zeros(shape=(x.shape[0], y.shape[0]))
f1.plot_surface(x_mat, y_mat, z_below,
                facecolors=colors2, edgecolor='none', rstride=1, vmin=0)
# Setting the zlimits
f1.set_zlim([0, np.max(z)])
plt.show()

The above results in the following plot以上结果在下图中在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM