1

背景:

我正在开发一个程序来显示 3d 数据的 2d 横截面。数据以 x、y、z1、z2、z3 等格式存储在一个简单的文本 csv 文件中。我取一个起点和终点,并浏览数据集(约 110,000 行)以在这些点之间创建一行点两个位置,并将它们转储到一个数组中。这工作得很好,而且相当快(大约需要 0.3 秒)。然后显示这条线,我一直在创建一个 matplotlib 堆积条形图。但是,程序的总运行时间约为 5.5 秒。我已将大部分内容(价值 3 秒)缩小到下面的代码。
'values' 是一个包含 x、y 和 z 值加上前导标识符的数组,这部分代码中没有使用它。第一个 plt.bar 用于绘制条形部分,第二个用于创建 -2000 的任意楼层。为了生成连续查看的部分,我在每个条形之间使用了一个零间隔。

    import matplotlib.pyplot as plt

    for values in crossSection:
        prevNum = None
        layerColour = None
        if values != None:
            for i in range(3, len(values)):
                if values[i] != 'n':
                    num = float(values[i].strip())
                    
                    if prevNum != None:
                        plt.bar(spacing, prevNum-num, width=interval, \
                                bottom=num, color=layerColour, \
                                edgecolor=None, linewidth=0)
                        
                    prevNum = num
                    
                    layerColour = layerParams[i].strip()
                    
            if prevNum != None:        
                plt.bar(spacing, prevNum+2000, width=interval, bottom=-2000, \
                                    color=layerColour, linewidth=0)
        
        spacing += interval

我确信有一种更有效的方法可以做到这一点,但我是 Matplotlib 的新手,仍然不熟悉它的功能。代码中时间的另一个主要用途是:

plt.savefig('output.png')

这大约需要一秒钟,但我认为这是可以保存文件的,我对此无能为力。

问题:

plt.bar()有没有更快的方法通过使用更好的或不同的 Matplotlib 函数来生成相同的输出(堆积条形图或类似的东西) ?

编辑: 我忘了在原始帖子中提到我正在使用 Python 3.2.3 和 Matplotlib 1.2.0

4

2 回答 2

2

将其留在这里以防有人遇到同样的问题...
虽然与 using 不完全相同,但使用bar()足够大的数据集(足够大以至于 usingbar()需要几秒钟),结果与stackplot(). 如果我使用 tcaswell 给出的方法将数据分类成图层并将其输入stackplot()到图表中,则会在 0.2 秒内创建,而不是 3 秒。

编辑

tcaswell 提供的将数据转为层的代码:

accum_values = []
for values in crosssection:
    accum_values.append([float(v.strip()) for v iv values[3:]])
accum_values = np.vstack(accum_values).T 
layer_params = [l.strip() for l in layerParams]
bottom = numpy.zeros(accum_values[0].shape)
于 2013-01-11T00:26:48.637 回答
1

看起来您正在绘制每个条形图,您可以将序列传递给bar(参见此 示例

我认为是这样的:

accum_values = []
for values in crosssection:
    accum_values.append([float(v.strip()) for v iv values[3:]])


accum_values = np.vstack(accum_values).T 
layer_params = [l.strip() for l in layerParams]
bottom = numpy.zeros(accum_values[0].shape)

ax = plt.gca()
spacing = interval*numpy.arange(len(accum_values[0]))
for data,color is zip(accum_values,layer_params):
    ax.bar(spacing,data,bottom=bottom,color=color,linewidth=0,width=interval)
    bottom += data

会更快(因为对 bar 的每次调用都会创建一个BarContainer,我怀疑您的问题的根源是您为每个 bar 创建一个,而不是为每一层创建一个)。

我真的不明白你在用顶部低于底部的条做什么,所以我没有尝试实现它,所以你必须稍微调整一下。

于 2013-01-10T04:18:04.910 回答