我有两个相应数据(x和y)数组,我在上面的对数 - 对数图上绘制。目前数据过于细化,我想将它们分开以获得更平滑的关系。我是否可以获得一些关于如何沿着x轴(以指数区域大小)进行分区的指导,以便它在对数对数刻度上显示为线性?
例如,如果第一个bin的范围是x = 10 ^ 0到10 ^ 1,我想收集该范围内相应x的所有y值,并将它们平均为该bin的一个值。我不认为np.hist或plt.hist很有效,因为他们通过计算事件来进行分箱。
编辑:对于上下文,如果有帮助,上面的图是一个协调性图,用于绘制某个网络的输入与输出程度。
答案 0 :(得分:1)
你可以用熊猫来实现这个目标。我们的想法是使用np.digitize
将每个X值分配给一个区间。由于您使用的是对数刻度,因此使用np.logspace
选择指数变化长度的间隔是有意义的。最后,您可以在每个区间中对X值进行分组并计算平均Y值。
import pandas as pd
import numpy as np
x_max = 10
xs = np.exp(x_max * np.random.rand(1000))
ys = np.exp(np.random.rand(1000))
df = pd.DataFrame({
'X': xs,
'Y': ys,
})
df['Xbins'] = np.digitize(df.X, np.logspace(0, x_max, 30, base=np.exp(1)))
df['Ymean'] = df.groupby('Xbins').Y.transform('mean')
df.plot(kind='scatter', x='X', y='Ymean')
答案 1 :(得分:1)
您可以使用scipy.stats.binned_statistic
获取每个bin中数据的平均值。最好通过numpy.logspace
创建垃圾箱。然后你可以绘制那些方法,例如作为横跨箱宽度或在平均位置散射的horiziontal线。
import numpy as np; np.random.seed(42)
from scipy.stats import binned_statistic
import matplotlib.pyplot as plt
x = np.logspace(0,5,300)
y = np.logspace(0,5,300)+np.random.rand(300)*1.e3
fig, ax = plt.subplots()
ax.scatter(x,y, s=9)
s, edges, _ = binned_statistic(x,y, statistic='mean', bins=np.logspace(0,5,6))
ys = np.repeat(s,2)
xs = np.repeat(edges,2)[1:-1]
ax.hlines(s,edges[:-1],edges[1:], color="crimson", )
for e in edges:
ax.axvline(e, color="grey", linestyle="--")
ax.scatter(edges[:-1]+np.diff(edges)/2, s, c="limegreen", zorder=3)
ax.set_xscale("log")
ax.set_yscale("log")
plt.show()