matplotlib 使用枚举作为ipywidget上的选项值

4ioopgfo  于 2022-11-15  发布在  其他
关注(0)|答案(2)|浏览(150)

我想用一个ipywidgets下拉菜单来创建一个条形图。条形图的条可以用不同的方式排序。
我有一个枚举类型的排序,我希望给予选项:

class SORT_TYPE(Enum):
    ALPHABETICAL = 1
    ASCENDING = 2
    DESCENDING = 3
    UNSORTED = 4

我有一个下拉小部件,其中的值使用上面的枚举

ordering_dropdown = widgets.Dropdown(
    options={'Alphabetical': SORT_TYPE.ALPHABETICAL, \
             'Ascending': SORT_TYPE.ASCENDING, \
             'Descending': SORT_TYPE.DESCENDING, \
             'Unsorted': SORT_TYPE.UNSORTED},
    value=SORT_TYPE.ALPHABETICAL,
    description='Ordering: ',
)

但当我在互动中使用它时

interactive(my_func, p1=p1, p2=p2, ordering=ordering_dropdown)

我得到

ValueError: <SORT_TYPE.ALPHABETICAL: 1> cannot be transformed to a widget

你知道我做错了什么吗?
先谢谢你。

pu3pd22g

pu3pd22g1#

回答我自己。我认为错误是因为枚举不是固定类型。我已经将枚举更改为

SORT_TYPE={'ALPHABETICAL': 1,\
       'ASCENDING': 2,\
       'DESCENDING': 3,\
       'UNSORTED': 4}

和下拉列表

ordering_dropdown = widgets.Dropdown(
       options={'Alphabetical': SORT_TYPE['ALPHABETICAL'], \
                'Ascending': SORT_TYPE['ASCENDING'], \
                'Descending': SORT_TYPE['DESCENDING'], \
                'Unsorted': SORT_TYPE['UNSORTED']},
       value=SORT_TYPE['ALPHABETICAL'],
       description='Ordering: ',
    )

它现在表现好一点了。

g52tjvyc

g52tjvyc2#

虽然您 * 可以 * 定义自己的Map并将其视为常量,但IntEnum(标准库)和StrEnum (third party package, but in the standard library as of Python 3.11)更接近您的初衷:

In [1]: from enum import IntEnum

In [2]: class MyEnum(IntEnum):
   ...:     ONE = 1
   ...:     TWO = 2
   ...:

In [3]: MyEnum.TWO
Out[3]: <MyEnum.TWO: 2>

In [4]: MyEnum.TWO.value  # <-- deflate via the value property
Out[4]: 2

In [5]: MyEnum(2)  # <-- reinflate by passing the int value to the constructor
Out[5]: <MyEnum.TWO: 2>

如果你无法访问StrEnum,那么你可以使用前面提到的SE答案中的技巧来近似类似的东西。我们可以利用选择部件的某个属性(例如DropdownRadioButtons等)来提供字符串和枚举之间的自动转换。
您可以通过传递一个列表来指定可选选项的枚举(选项可以是(label,value)对,也可以是通过调用str为其派生标签的值)。
提供枚举语意(Semantics),使字串与其Map的枚举值之间有更紧密的相关性。

class SORT_TYPE(str, Enum):  # <-- or just StrEnum, if you have it
    ALPHABETICAL = "Alphabetical"
    ASCENDING = "Descending"
    DESCENDING = "Descending"
    UNSORTED = "Unsorted"

ordering_dropdown = widgets.Dropdown(
    options=[
        (
            sort_type.value,  # the label (a str)
            sort_type,  # the value (an enum)
        ) for sort_type in SORT_TYPE
    ],
    value=SORT_TYPE.ALPHABETICAL,  # probably must be in options
    description='Ordering: ',
)

从您的小部件检索回值将导致枚举:

assert isinstance(ordering_dropdown.value, SORT_TYPE)  # should work

相关问题