7

我正在尝试使用包含 ca.matplotlib 的散点图。约 2000 万个数据点。即使在最终没有可见数据之前将 alpha 值设置为最低之后,结果也只是一个完全黑色的图。

plt.scatter(timedPlotData, plotData, alpha=0.01, marker='.')

x 轴是大约 2 个月的连续时间线,y 轴由 150k 个连续整数值组成。

有没有办法绘制所有点,以便它们随时间的分布仍然可见?

谢谢您的帮助。

4

4 回答 4

14

有不止一种方法可以做到这一点。很多人建议使用热图/内核密度估计/二维直方图。@Bucky 建议使用移动平均线。此外,您可以在移动最小值和移动最大值之间进行填充,并将移动平均值绘制在顶部。我经常称其为“块图”,但这是一个可怕的名字。下面的实现假设您的时间 (x) 值是单调递增的。如果不是,那么在函数中“分块”之前y进行排序就足够简单了。xchunkplot

这里有几个不同的想法。哪个最好取决于你想在情节中强调什么。请注意,这将是相当缓慢的运行,但这主要是由于散点图。其他绘图样式要快得多

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime as dt
np.random.seed(1977)

def main():
    x, y = generate_data()
    fig, axes = plt.subplots(nrows=3, sharex=True)
    for ax in axes.flat:
        ax.xaxis_date()
    fig.autofmt_xdate()

    axes[0].set_title('Scatterplot of all data')
    axes[0].scatter(x, y, marker='.')

    axes[1].set_title('"Chunk" plot of data')
    chunkplot(x, y, chunksize=1000, ax=axes[1],
              edgecolor='none', alpha=0.5, color='gray')

    axes[2].set_title('Hexbin plot of data')
    axes[2].hexbin(x, y)

    plt.show()

def generate_data():
    # Generate a very noisy but interesting timeseries
    x = mdates.drange(dt.datetime(2010, 1, 1), dt.datetime(2013, 9, 1),
                      dt.timedelta(minutes=10))
    num = x.size
    y = np.random.random(num) - 0.5
    y.cumsum(out=y)
    y += 0.5 * y.max() * np.random.random(num)
    return x, y

def chunkplot(x, y, chunksize, ax=None, line_kwargs=None, **kwargs):
    if ax is None:
        ax = plt.gca()
    if line_kwargs is None:
        line_kwargs = {}
    # Wrap the array into a 2D array of chunks, truncating the last chunk if
    # chunksize isn't an even divisor of the total size.
    # (This part won't use _any_ additional memory)
    numchunks = y.size // chunksize
    ychunks = y[:chunksize*numchunks].reshape((-1, chunksize))
    xchunks = x[:chunksize*numchunks].reshape((-1, chunksize))

    # Calculate the max, min, and means of chunksize-element chunks...
    max_env = ychunks.max(axis=1)
    min_env = ychunks.min(axis=1)
    ycenters = ychunks.mean(axis=1)
    xcenters = xchunks.mean(axis=1)

    # Now plot the bounds and the mean...
    fill = ax.fill_between(xcenters, min_env, max_env, **kwargs)
    line = ax.plot(xcenters, ycenters, **line_kwargs)[0]
    return fill, line

main()

在此处输入图像描述

于 2013-09-18T19:33:57.193 回答
3

对于每一天,计算每个值的频率(一个 collections.Counter 会很好地做到这一点),然后绘制一个值的热图,每天一个。对于发布,对热图颜色使用灰度。

于 2013-09-18T18:47:37.950 回答
1

每天将值分组到带中,并使用计数、值带、天的 3d 直方图。

这样,您就可以清楚地获得每天给定波段中的出现次数。

于 2013-09-18T20:29:45.770 回答
1

我的建议是在绘制原始数据之前对原始数据使用排序和移动平均算法。这应该在感兴趣的时间段内保持平均值和趋势不变,同时减少图上的混乱。

于 2013-09-18T18:09:50.097 回答