【问题标题】:Scatter plot with varying Quantile/Percentile in python [duplicate]python中具有不同分位数/百分位数的散点图[重复]
【发布时间】:2021-06-09 15:27:27
【问题描述】:

基本上,我想在具有不同百分位数的两个变量之间绘制散点图,我已经使用以下玩具代码绘制了散点图,但我无法为不同的百分位数(分位数)绘制它。

quantiles = [1,10,25,50,50,75,90,99]
grays = ["#DCDCDC", "#A9A9A9", "#2F4F4F","#A9A9A9", "#DCDCDC"]
alpha = 0.3
data = df[['area_log','mr_ecdf']]
y = data['mr_ecdf']
x = data['area_log']
idx   = np.argsort(x)
x = np.array(x)[idx]
y = np.array(y)[idx]
for i in range(len(quantiles)//2):   
    plt.fill_between(x, y, y, color='black', alpha = alpha, label=f"{quantiles[i]}")
    lower_lim = np.percentile(y, quantiles[i])
    upper_lim = np.percentile(y, 100-quantiles[i])
    data = data[data['mr_ecdf'] >= lower_lim]
    data = data[data['mr_ecdf'] <= upper_lim]   
    y = data['mr_ecdf']
    x = data['area_log']
    idx   = np.argsort(x)
    x = np.array(x)[idx]
    y = np.array(y)[idx]
data = df[['area_log','mr_ecdf']]
y = data['mr_ecdf']
x = data['area_log']
plt.scatter(x, y,s=1, color = 'r', label = 'data')
plt.legend()
# axes.set_ylim([0,1])

enter image description here 数据链接:here

我想绘制这样的图(First- (1,1)):

【问题讨论】:

标签: python matplotlib machine-learning regression data-visualization


【解决方案1】:

正如@Mr.所提到的。 T,一种方法是自己计算 CI,然后使用plt.fill_between 绘制它们。您显示的数据存在问题,因为没有足够的点和方差,因此您永远无法获得图片上的内容(而且我图中的分隔也不清楚,所以我在下面放了另一个示例来说明它是如何工作的) .如果您有这方面的数据,请发布它,我会更新。无论如何,您应该检查我在评论中提到的post,并遵循以下一些方法:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([5,7,8,7,2,17,2,9,4,11,12,9,6])
y = np.array([99,86,87,88,111,86,103,87,94,78,77,85,86])

idx   = np.argsort(x)

x = np.array(x)[idx]
y = np.array(y)[idx]

# Create a list of quantiles to calculate
quantiles = [0.05, 0.25, 0.75, 0.95]
grays = ["#DCDCDC", "#A9A9A9", "#2F4F4F","#A9A9A9", "#DCDCDC"]

alpha = 0.3

plt.fill_between(x, y-np.percentile(y, 0.5), y+np.percentile(y, 0.5), color=grays[2], alpha = alpha, label="0.50")

# if the percentiles are symmetrical and we want labels on both sides
for i in range(len(quantiles)//2):
    plt.fill_between(x, y, y+np.percentile(y, quantiles[i]), color=grays[i], alpha = alpha, label=f"{quantiles[i]}")
    plt.fill_between(x, y-np.percentile(y, quantiles[-(i+1)]),y, color=grays[-(i+1)], alpha = alpha, label=f"{quantiles[-(i+1)]}")

plt.scatter(x, y, color = 'r', label = 'data')
plt.legend()

编辑: 一些解释。我不确定我的代码中有什么不正确的地方,但如果你能告诉我,我会很高兴——总有一种改进的方法(再次感谢@Mr T.)。然而,函数之间的填充执行以下操作:

填充两条水平曲线之间的区域。 曲线由点 (x, y1) 和 (x, y2) 定义

因此,您可以通过 y1 和 y2 来指定要让图形填充颜色的位置。再举一个例子:

X = np.linspace(120, 50, 71)
Y = X + 20*np.random.randn(71)
plt.fill_between(X, Y-np.percentile(Y, 95),Y+np.percentile(Y, 95), color="k", alpha = alpha)
plt.fill_between(X, Y-np.percentile(Y, 80),Y+np.percentile(Y, 80), color="r", alpha = alpha)
plt.fill_between(X, Y-np.percentile(Y, 60),Y, color="b", alpha = alpha)
plt.scatter(X, Y, color = 'r', label = 'data')

我生成了一些随机数据来看看发生了什么。 plt.fill_between(X, Y-np.percentile(Y, 60),Y, color="b", alpha = alpha) 线仅绘制从Y 下方的第 60 个百分位到 Y 的填充。另外两行总是从Y 的两侧覆盖空间(因此是+-)。您可以看到百分位数重叠,当然,它们必须重叠——90 个百分位数也包括 60 个。所以你只看到它们之间的差异。您可以按相反的顺序绘制数据(或更改 z 因子),但随后所有数据都将被最高百分位数覆盖。我希望这可以澄清答案。另外,您的问题很好,如果我的回答感觉不中立,请见谅。只要您还有图表数据而不仅仅是图片,我/其他人的答案可能会更加量身定制:)。

【讨论】:

  • 非常抱歉;你的解决方案真的很有帮助,我不是故意冒犯你的。你能解释一下fill_between是如何工作的吗,我尝试调整并发现它用最后一个百分位填充所有东西,即在这种情况下为0.95,我猜其他百分位带被最高百分位覆盖了?你能帮忙吗?
  • 这个答案不是我写的; @MyWork 没有写你提到的评论。而且这个应答码不能正常工作是正确的。
  • @MyWork 首先:计算您的绘图生成的波段数。 print(i, q, quantiles[-i]) 可能会提示您循环有什么问题。您可能还想尝试沿 x 轴分布不均的其他数据,例如 x = np.random.normal(50, 20, n)
  • @Mr.T,你说得对,非常感谢,我的错。 For 循环已修复。
  • @MyWork 谢谢你的解释。现在,我明白了工作。但它所做的是扩大 Y 范围,我尝试了一些方法并用原始数据更新了问题。请看一看。
猜你喜欢
  • 2017-08-30
  • 2014-09-06
  • 2020-05-11
  • 2022-01-22
  • 2020-05-28
  • 1970-01-01
  • 2017-11-20
  • 2021-08-16
  • 1970-01-01
相关资源
最近更新 更多