Open MarcSkovMadsen opened 3 years ago
If you want to preserve the order of columns (right now) you can do this
pn.pane.Perspective(df, columns=list(df.columns)).servable()
Just to be clear - I think it should be a possibility to add an iterable as a column
input.
A way to do this is replace param.List
with the following for the column
parameter. I don't know if there is a more correct way to do this but this seems the easiest to implement.
class ListLike(param.List):
def _validate(self, val):
if hasattr(val, "__iter__"):
val = list(val)
return super()._validate(val)
What is your opinion of this @philippjfr?
Not sure, maybe we should add an option to param.List
and param.Tuple
to accept iterables and automatically cast them to the declared type rather than introducing new parameters. @jbednar any thoughts?
What would be the cons or risks of doing what you suggest philippjfr?
Well I wouldn't change the default behavior so we'd still have to update the param.List
definitions in Panel where appropriate.
The only one I see is that param.List
and param.Tuple
would not hold the instance it was initially provided. That might be confusing for some use cases?
That's definitely true, not so important for param.Tuple since tuples are immutable but I can imagine a user trying to modify the list the passed to a parameter inplace. I wouldn't say that's a recommended workflow though.
Good question. In general it seems safe for Param to cast scalars to the indicated type (as recently proposed for Numpy integer scalars), but there is a large potential for confusion when converting mutable types, where the user could later change them and expect that value to be present in the Parameter value.
Would it be sufficient if we raised a more explicit error message in this case? I.e., check if the argument is iterable and if so tell the user to convert it to a list first? That way the onus is on the user to decide whether it's safe to cast it.
Honestly I'm kind of in the camp that either you should never modify mutable types held by a param inplace (and we should automatically wrap them in an equivalent immutable subclass) or we should provide mutable wrappers which notify panel if they have been modified. Because right now you can modify mutables and param.watch
callbacks will have no idea, which frequently trips up users.
I don't think it's that clear. E.g. Topographica, for which Param was built, had many objects with Parameter values that were Python class instances, and in such cases it's only making use of the identity of the object, not the current state, and nothing needs to be triggered at all when that state changes; the parameter value is just a selection of one object out of the many available objects. The same can be true of a param.List, which might specify some subset of a set of mutable Python objects. But I suppose in this case you'd want a notification when the list changes, not when one of the items in the list changes? If so, yes, that might be nice, but I don't know how to achieve it. I do know that automatically coercing some object into a list won't make that any easier!
Totally agree that there are varying needs for different projects here, although I'd argue Panel param.watch
based usage now far exceeds the number of original users which preceded support for that.
If so, yes, that might be nice, but I don't know how to achieve it.
Bokeh uses list/dict subclasses which have mutation observers to achieve this.
Totally agree that there are varying needs for different projects here, although I'd argue Panel param.watch based usage now far exceeds the number of original users which preceded support for that.
Sure, but I don't think selecting one of a finite set of mutable objects is a rare case even now, and would not normally mean we'd want to trigger on a mutation to that object. But triggering on the list or dict itself changing does indeed seem like a common need.
Panel 0.11:
If I run the below python code it raises an
ValueError: List 'columns' must be a list.
.Solution
Support specifying the
columns
as an iterable.Additional Context
The reason why I specify the columns is that I want to preserve the column order of the dataframe. When using
Perspective
they are ordered alphabetically.