Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python matplotlib中是否有行为类似于alpha但反向的内容?_Python_Matplotlib - Fatal编程技术网

Python matplotlib中是否有行为类似于alpha但反向的内容?

Python matplotlib中是否有行为类似于alpha但反向的内容?,python,matplotlib,Python,Matplotlib,显示图中数据点集中的一个好方法是使用具有非单位透明度的散点图。因此,浓度越高的区域越暗 # this is synthetic example N = 10000 # a very very large number x = np.random.normal(0, 1, N) y = np.random.normal(0, 1, N) plt.scatter(x, y, marker='.', alpha=0.1) # an area full of dots, darker wh

显示图中数据点集中的一个好方法是使用具有非单位透明度的散点图。因此,浓度越高的区域越暗

# this is synthetic example
N = 10000       # a very very large number
x = np.random.normal(0, 1, N)
y = np.random.normal(0, 1, N)
plt.scatter(x, y, marker='.', alpha=0.1)  # an area full of dots, darker wherever the number of dots is more
这就产生了这样的结果:

想象一下我们想要强调的异常值的情况。因此,情况几乎相反:一个较不集中的地区更大胆的阴谋。(对于我的简单示例,可能有一个技巧可以应用,但请想象一个一般情况,即之前不知道点的分布,或者很难定义颜色的透明度/权重规则。)

我在想,是否有专门为这项工作设计的与
alpha
一样方便的东西。尽管强调异常值的其他想法也受到欢迎


更新:这是当多个数据点分散在同一区域时发生的情况:

我在寻找下面的图片,数据点越多,标记的透明度越低


我不知道它是否对您有帮助,因为它不是您要求的,但您可以简单地对点进行着色,这些点的值大于某个阈值。例如:

import matplotlib.pyplot as plt

num = 100
threshold = 80

x = np.linspace(0, 100, num=num)
y = np.random.normal(size=num)*45

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(x[np.abs(y) < threshold], y[np.abs(y) < threshold], color="#00FFAA")
ax.scatter(x[np.abs(y) >= threshold], y[np.abs(y) >= threshold], color="#AA00FF")
plt.show()
导入matplotlib.pyplot作为plt
num=100
阈值=80
x=np.linspace(0,100,num=num)
y=np.随机.正常(大小=num)*45
图=plt.图()
ax=图添加子批次(1,1,1)
最大散射(x[np.abs(y)=threshold],y[np.abs(y)>=threshold],color=“#AA00FF”)
plt.show()

据我所知,这个非常有趣的问题没有“直接”的解决方案。作为一种解决方法,我提出以下解决方案:

N = 10000       # a very very large number
x = np.random.normal(0, 1, N)
y = np.random.normal(0, 1, N)
fig = plt.figure()  # create figure directly to be able to extract the bg color
ax = fig.gca()
ax.scatter(x, y, marker='.')  # plot all markers without alpha
bgcolor = ax.get_facecolor()  # extract current background color
# plot with alpha, "overwriting" dense points
ax.scatter(x, y, marker='.', color=bgcolor, alpha=0.2)
这将在没有透明度的情况下打印所有点,然后以某种透明度再次打印所有点,“覆盖”密度最高的点最多。将
alpha
值设置为其他更高的值将更加强调异常值,反之亦然

当然,第二个散点图的颜色需要调整为背景色。在我的示例中,这是通过提取背景色并将其设置为新散点图的颜色来完成的

此解决方案与分布类型无关。它只取决于点的密度。但是,它生成的点数量是点数量的两倍,因此渲染可能需要稍长的时间


复制问题中的编辑,我的解决方案正好显示了所需的行为。最左边的点是一个点,是最暗的,最右边的点由三个点组成,是最亮的颜色

x = [0, 1, 1, 2, 2, 2]
y = [0, 0, 0, 0, 0, 0]
fig = plt.figure()  # create figure directly to be able to extract the bg color
ax = fig.gca()
ax.scatter(x, y, marker='.', s=10000)  # plot all markers without alpha
bgcolor = ax.get_facecolor()  # extract current background color
# plot with alpha, "overwriting" dense points
ax.scatter(x, y, marker='.', color=bgcolor, alpha=0.2, s=10000)

假设分布以特定点为中心(例如,在本例中为(0,0)),我将使用以下公式:

import numpy as np
import matplotlib.pyplot as plt

N = 500
# 0 mean, 0.2 std
x = np.random.normal(0,0.2,N)
y = np.random.normal(0,0.2,N)

# calculate the distance to (0, 0).
color = np.sqrt((x-0)**2 + (y-0)**2)

plt.scatter(x , y, c=color, cmap='plasma', alpha=0.7)
plt.show()
结果:


回答这个问题:您可以计算点的密度,对其进行规格化,并在彩色贴图的alpha通道中对其进行编码

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

# this is synthetic example
N = 10000       # a very very large number
x = np.random.normal(0, 1, N)
y = np.random.normal(0, 1, N)


fig, (ax,ax2) = plt.subplots(ncols=2, figsize=(8,5))
ax.scatter(x, y, marker='.', alpha=0.1)

values = np.vstack([x,y])
kernel = stats.gaussian_kde(values)
weights = kernel(values)
weights = weights/weights.max()

cols = plt.cm.Blues([0.8, 0.5])
cols[:,3] = [1., 0.005]
cmap = LinearSegmentedColormap.from_list("", cols)

ax2.scatter(x, y, c=weights, s = 1, marker='.', cmap=cmap)

plt.show()

左侧是原始图像,右侧是高密度点的alpha值较低的图像

但是,请注意,这是不需要的,因为高密度透明点与低密度透明点无法区分。也就是说,在正确的图像中,你的分布看起来好像有一个洞。 显然,使用不包含背景颜色的彩色贴图的解决方案对读者来说不会那么容易混淆

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

# this is synthetic example
N = 10000       # a very very large number
x = np.random.normal(0, 1, N)
y = np.random.normal(0, 1, N)

fig, ax = plt.subplots(figsize=(5,5))

values = np.vstack([x,y])
kernel = stats.gaussian_kde(values)
weights = kernel(values)
weights = weights/weights.max()

ax.scatter(x, y, c = weights, s=9, edgecolor="none", marker='.', cmap="magma")

plt.show()


这里,低密度点仍然被深色所遮蔽,但同时也清楚地看到,最高密度位于中间。

使用稍大的标记物如何?使用pcolor或pcolormesh,这将内在地传递有关细胞密度的信息。@cmaureir在您的评论之后,我添加了一段代码来澄清这种情况。在这种情况下,大标记将填满整个绘图,而异常值几乎不可见。@arash那么我的解决方案有什么问题?它会生成您在问题扩展中发布的bahvior。请看我的答案中的编辑,以复制您的示例。也请看一看,我认为有一种方法可以使用和图像/网格,用于备用区域中的密集区域和点。不幸的是,这不适用于所有情况。你通常不知道阈值。另外,分布浓度可能不是
x
y
的简单函数。是的,如果分布不同,那么这个解决方案是错误的。但是,如果分布很简单(如我的代码生成的图形上),则可以将阈值定义为最大值的80%(或1,5倍中值)。这将扩大此代码的使用范围。这是一个很好的技巧!尽管如此,正如您所说,它将使渲染时间加倍,我不确定对于数据点太多的情况,它是否仍然是一个可行的解决方案。不过,我相信只要
matplotlib
不为软件包提供此功能,它就是最通用的解决方案之一。谢谢!是的,渲染时间是一个缺点。但对于2e6点,在我的机器上完全矢量化的输出大约是4秒。所以我认为这仍然是可以接受的。由于这是一个可能很少被追问的问题,我认为matplotlib不会很快包含这样的内容。另一方面,我发现这个问题非常有趣。我经常使用回归和机器学习,我已经看到了成千上万的应用程序这是一个很好的创意。我完全同意,在我的例子中,它几乎传达了我的意图。然而,使用高斯核(特别是w/o提供的
bw_方法
)可能最终会产生误导性的图(想象一下,即使我们不知道分布,我们也不知道簇的典型大小的情况)。我坚信在
matplotlib
中处理颜色的内部函数是最好的方法。因为它增加了软件包和mor的灵活性