用Memcache缓存Matplotlib(Wont Pickle) [英] Caching Matplotlib with Memcache (Wont Pickle)

查看:109
本文介绍了用Memcache缓存Matplotlib(Wont Pickle)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绘制的图表需要3秒钟,然后可以从其中添加了一些东西的所述图表制作子图表.我想从主图表中缓存轴,以便在呈现子图表时可以检索它并在以后对其进行修改.我该如何克服这个错误?

I have a chart that is rendered takes 3 seconds and then subcharts that can be made from said chart where things are added to it. I want to cache the axes from the main chart so that I can retrieve it and modify it later when rendering the subcharts. How can I get past this error?

这里有一个示例测试代码:

Heres a sample test code:

import pylibmc
cache = pylibmc.Client(["127.0.0.1"], binary=True, behaviors={"tcp_nodelay": True, "ketama": True})
import matplotlib.pyplot as plt


cache_name = 'test'
fig = plt.figure(figsize=(20, 7))
ax = fig.add_axes([0, 0.15, 0.98, 0.85])
cache.set(cache_name, ax, 300)

哪个出现以下错误:

cPickle.PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

无论如何,我可以使它正常工作吗?

Is there anyway I could get this to work?

推荐答案

这里有关于matplotlib图形能够序列化的讨论.我还没有看到任何报告表明已解决或什至已将其作为目标的报告.因此,如果您尝试通过电线将其发送到memcached,则其显然将失败.我在搜索时发现的讨论表明,matplotlib的当前设计不能轻松满足此目标,并且需要对内部结构进行重构.参考: http://old.nabble.com/matplotlib-figure-serialization-td28016714 .html

There are discussion out there regarding the desire for matplotlib figures to be able to be serialized. I haven't seen anything that reports this has been addressed or even accepted as a goal. So if you try to send them over the wire to memcached, its obviously going to fail. The discussions that I have found when searching suggest that the current design of matplotlib doesn't cater to this goal easily, and it would require a refactor of the internals. Reference: http://old.nabble.com/matplotlib-figure-serialization-td28016714.html

您可以做的是,将数据重新组织到数据集中,并且只需调用一次ax.bar(),就可以大大减少执行时间.然后可以将数据集序列化并以您想要的任何格式存储(例如,放入memcached).

What you could do, to dramatically reduce your execution time, is to reorganize your data into a dataset, and only call ax.bar() once. The dataset can then be serialized and stored in whatever format you want (into memcached for instance).

这是一个代码示例,显示了您的方法与将它们组合到数据集中的方法之间的测试.如果需要,可以在此处更轻松地查看它: https://gist.github.com/2597804

Here is a code example showing the test between your approach, and one that combines them into a dataset. You can view it here more easily if you want: https://gist.github.com/2597804

import matplotlib.pyplot as plt
from random import randint 
from time import time 

DATA = [
    (i, randint(5,30), randint(5,30), randint(30,35), randint(1,5)) \
    for i in xrange(1, 401)
]

def mapValues(group):
    ind, open_, close, high, low = group
    if open_ > close: # if open is higher then close
        height = open_ - close # heigth is drawn at bottom+height
        bottom = close
        yerr = (open_ - low, high - open_)
        color = 'r' # plot as a white barr
    else:
        height = close - open_ # heigth is drawn at bottom+height
        bottom = open_
        yerr = (close - low, high - close)
        color = 'g' # plot as a black bar

    return (ind, height, bottom, yerr, color)

#
# Test 1
#
def test1():
    fig = plt.figure()
    ax = fig.add_subplot(111)

    data = map(mapValues, DATA)

    start = time()

    for group in data: 

        ind, height, bottom, yerr, color = group

        ax.bar(left=ind, height=height, bottom=bottom, yerr=zip(yerr), 
                color=color, ecolor='k', zorder=10,
                error_kw={'barsabove': False, 'zorder': 0, 'capsize': 0}, 
                alpha=1)

    return time()-start

#
# Test 2
#
def test2():
    fig = plt.figure()
    ax = fig.add_subplot(111)

    # plotData can be serialized
    plotData = zip(*map(mapValues, DATA))

    ind, height, bottom, yerr, color = plotData

    start = time()

    ax.bar(left=ind, height=height, bottom=bottom, yerr=zip(*yerr), 
            color=color, ecolor='k', zorder=10,
            error_kw={'barsabove': False, 'zorder': 0, 'capsize': 0}, 
            alpha=1)

    return time()-start


def doTest(fn):
    end = fn()
    print "%s - Sec: %0.3f, ms: %0d" % (fn.__name__, end, end*1000)



if __name__ == "__main__":
    doTest(test1)
    doTest(test2)

    # plt.show()

结果:

python plot.py 
test1 - Sec: 1.592, ms: 1592
test2 - Sec: 0.358, ms: 357

这篇关于用Memcache缓存Matplotlib(Wont Pickle)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆