【问题标题】:Why does matplotlib's Slider only allow a range of 0-7?为什么 matplotlib 的 Slider 只允许 0-7 的范围?
【发布时间】:2012-10-20 04:14:22
【问题描述】:

我正在尝试在 1 个字节上绘制按位循环移位的值。我想要一个滑块让我更改原始输入值。我使用 matplotlib 站点上的滑块示例作为参考,但由于某种原因,即使我在运行脚本时将 0-255 作为滑块范围传递,范围始终为 0-7。我猜想滑块以某种方式被锁定到我的最大 x 值数量,但我不知道如何。如何让滑块让我选择完整的 0-255 范围?

此外,尽管我给了滑块的最小值/最大值,但它会在前面插入一些填充以低于 0,并在滑块中间随机绘制一条垂直线。我该如何摆脱它? (还有什么用?目的对我来说并不明显)

滑块的图片仅上升到 7:

代码:

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

from numpy import uint8
from numpy import uint16
from numpy import uint32
from numpy import uint64

def sizeof(x):
    return [uint8, uint16, uint32, uint64].index(x) + 1

def rot(x, i):
    return type(x)((x >> i) | (x << (sizeof(type(x))*8 - i))) 

def plotShifts(x):
    origType = type(x)
    maxval = type(x)(-1)

    numrots = sizeof(type(x)) * 8
    vals = [rot(x, i) for i in range(numrots)]

    print vals

    l, = plt.plot(range(numrots), vals, 'ro')

    axcolor = 'lightgoldenrodyellow'
    inputax = plt.axes([0.15, 0.05, 0.65, 0.03], axisbg=axcolor)
    inputsl = Slider(inputax, 'Input', 0, maxval, valinit=0, valfmt="%d")

    def update(x):
        vals = [rot(origType(x), i) for i in range(numrots)]
        l.set_ydata(vals)
        plt.draw()
    inputsl.on_changed(update)

    plt.axis([-0.5, numrots-1 + 0.5, -2, maxval + 2])

plotShifts(uint8(1))
plt.show()

【问题讨论】:

    标签: python plot matplotlib bit-manipulation


    【解决方案1】:

    问题出在最后一行plt.axis([-0.5, numrots-1 + 0.5, -2, maxval + 2]) 上,它作用于保持滑块的轴,而不是作用于数据的轴。

    我建议使用matplotlib 的OO 接口而不是pyplot 接口来进行任何编程。 pyplot 接口非常适合交互的东西,但它有很多隐藏状态。

    由于回调的工作方式,您还需要返回对 slider 对象的引用。

    import matplotlib.pyplot as plt
    from matplotlib.widgets import Slider
    
    from numpy import uint8
    from numpy import uint16
    from numpy import uint32
    from numpy import uint64
    
    def sizeof(x):
        return 2 ** [uint8, uint16, uint32, uint64].index(x)
    
    def rot(x, i):
        return type(x)((x >> i) | (x << (sizeof(type(x))*8 - i))) 
    
    def plotShifts(x):
        fig = plt.figure() # make a new figure
        ax = fig.add_axes([0.15, 0.2, 0.65, 0.7]) # add data axes
        origType = type(x)
        maxval = type(x)(-1)
    
        numrots = sizeof(type(x)) * 8
        vals = [rot(x, type(x)(i)) for i in range(numrots)]
    
        print vals
        print maxval
        l, = ax.plot(range(numrots), vals, 'ro') # plot to data axes
    
        axcolor = 'lightgoldenrodyellow'
        inputax = fig.add_axes([0.15, 0.05, 0.65, 0.03], axisbg=axcolor)
        inputsl = Slider(inputax, 'Input', 0, maxval, valinit=0, valfmt="%d")
    
        def update(x):
            vals = [rot(origType(x), origType(i)) for i in range(numrots)]
            l.set_ydata(vals)
            plt.draw()
        inputsl.on_changed(update)
    
        ax.set_ylim([-2,maxval +2]) # set ylim on data axes
        ax.set_xlim([-.5,numrots-1+.05]) # set xlim on data axes
    
    
        return inputsl
    
    sldr = plotShifts(uint8(1))
    plt.show()
    

    【讨论】:

    • 哇!完全忘记了我是如何混合 OOP 和状态机接口的。
    • 我知道我可以调用轴来创建一个轴对象,因为我是为滑块做的,但是如何将它附加到绘图中?我现在尝试了一些变体,在绘图对象上调用 set_axes 或将其作为轴关键字传递给构造函数,它们都使我的绘图消失......
    • 非常感谢,太完美了:)
    【解决方案2】:

    很可能是因为 maxval =7 在这一行

    inputsl = Slider(inputax, 'Input', 0, maxval, valinit=0, valfmt="%d")
    

    【讨论】:

    • 是的,它是 255,因为当您将 -1 分配给无符号数时,您会得到最高的无符号数,对于 uint8 来说,它是 255。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 2021-06-03
    相关资源
    最近更新 更多