-
Notifications
You must be signed in to change notification settings - Fork 794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API: should Layer()
not derive from BaseObject
?
#93
Comments
What about defining a dir Method? Sent from my iPhone
|
Ah – that's a good idea! I'll try that. |
Traitlets even offers a method for getting a list of all the traitlets attributes - we could combine that with a list of the public methods Sent from my iPhone
|
Another option: what if we change |
Or maybe mark_* to be consistent with the VL naming of things ? Sent from my iPhone
|
I have alternative syntax to propose here. I'm not married to this idea yet, but think it's worth considering. Currently Altair rely on method chaining to describe mark.
What if we make mark first parameter of
Especially if we call the top-level object a View
I feel like this seems more natural, in a sense that we encode |
One of the core abstractions in altair is that everything is a strongly Thus, the Lastly, tab completion of the API is pretty important as in the notebook it On Thu, May 19, 2016 at 5:32 PM, Kanit Wongsuphasawat <
Brian E. Granger |
I make the |
On the tab-completion question – is there a way to make the traitlets keyword arguments show up in tab completion? That would be extremely helpful! |
I like the tab idea. So please ignore my comment above. :) That said, I wonder why you have to put mark after encode in the examples? For example, Why not: I think the latter is more consistent with how we write specs in Vega-Lite. |
To be clear, either order works currently. |
Yep. I mean, unless you have strong preference, can we put |
I don't feel too strongly about the ordering but like the idea of being consistent with the vegalite examples. So +1 to marking first Sent from my iPhone
|
Somewhat related: how would you feel about the For example, here's the current API for creating a red scatterplot: Layer(data, config=Config(mark=MarkConfig(color='red'))).mark_circle(
).encode(
x='Horsepower',
y='Miles_per_Gallon',
) Here's how we might do the same thing with mark keywords: Layer(data).mark_circle(
color='red'
).encode(
x='Horsepower',
y='Miles_per_Gallon',
) |
I would avoid adding syntax that diverge too much from Vega-Lite syntax because that would lead to confusion when you know one version and want to transition to use another. |
The My feeling is that Vega-lite is a specification (not an API), while Altair is an API (not a specification), so we should feel free to make these sorts of choices to make life easier for the user. |
Now you might ask why we have In the first, if you forget all the mark options you type |
I don't think so, for direct Vega-Lite users, our syntax is our API as well. So keeping similarity between the two projects would benefit both projects in longer term.
I actually don't feel against For config, this is a much bigger jump. ( For color's case, you can actually do
so I guess in Altair it could still be .encode(Color(value='red')) |
I guess one tricky part is that we can't do
because we can't distinguish between |
If a Python version of Vega-lite is what you're after, why use Altair at all? You could define things as Python dictionaries, and use |
All I know is that if I tell people that to make points red simply requires Layer(config=Config(mark=MarkConfig(color='red'))).mark_circle() they'll laugh and uninstall the package. |
I'm working on this now – it doesn't require the one-to-one mapping you have in mind. |
Ok. Your point about Layer(config=Config(mark=MarkConfig(color='red'))).mark_circle() or slightly better but still very terrible Layer().mark_circle().configure(mark=MarkConfig(color='red')) is a very good one. But I don't know if the proposed solution above is the right one. Is there a way to solve this that works for other type of config as well? (Btw, we have a Vega slack channel. If you want we can create Altair channel there so @jheer @ellisonbg and @domoritz can be in the same room.) |
I imagine that as we hit other pain points in configuration, we can come up with more API solutions similar to |
Maybe one way to have the best of both worlds is to make everything a top-level method. For example we could do something along the lines of Layer().configure_mark_color('red') which would be an alias of Layer().configure_mark(color='red') which would be an alaias of Layer().configure(mark=MarkConfig(color='red')) which would be an alias of Layer(config=Config(mark=MarkConfig(color='red'))) A benefit would be that |
The comment above is very interesting. Let's see what others think. If we do this alias thing, do we still do the Below the HR are my old reply before reading your latest comment Ok. I look at a few other vis spec language and think that maybe Here the problem is we want to distinguish between mapping to field and mapping to value. Given discusion above, we can't do like ggplot here because it introduces type inconsistency, which will screw up autocompletion. Thus, this solution maybe the right one. :)
Maybe that's the way to go. FYI, I look at our configs. The only ones that we have to think about are
|
OK – interesting to hear that there are other places where Vega-Lite allows configurations in multiple places. It might make sense for the spec to move to doing that more: e.g. rather than I think a good goal would be to make the Another unrelated thought as you talk about the spec evolving: does the spec have any place to specify the version used? If not, it's going to be hard to let it evolve without breaking a lot of people's visualizations. |
Thinking a bit more... I like the idea of having a set of configure_axis()
configure_cell()
configure_mark()
configure_facet()
configure_legend()
configure_scale() So then you can do things like However, for the case of the I am not very fond of the |
Yes. To be fair, I was a little inaccurate last night. Scale config is really for theming. (But when you set scale/axis/legend config, it applies for scale/axis/legend of every applicable channel.)
For Vega-Lite, I don't think we will do it.
Right now it's sort of like that. Many mark config (that are properties of the marks) will eventually become encoding channel and support mapping to field -- but that requires implementing default scale range, and legend support. Since the most useful channels are already supported, we do not plan to implement this yet and this might happen over time. But I guess we won't go to an extreme point where normal usage should "never" have to touch it directly (but yes, probably "rarely"). For example, some rarely used configs (e.g.,
Having a version would be useful. Right now we don't have it yet but we discussed about it in vega/vega#448. In any case, we will mostly add new properties more than removing. In general, we consider multiple alternative syntaxes (esp. the core part) before deciding on a syntax so this help avoid deprecating properties / major restructuring to support backward compatibility. But as you know, we can't 100% prevent this, so we definitely should add versioning in some form.
okay.
I agree that this should not be shown in examples (as the recommended way). Note that |
Let's make a decision on these points:
I am +1 on both... |
+1 if we're talking about the one-level-deep options... Not things like |
OK, I have to shift back to other stuff, feel free to work on this stuff... |
+1 too.
I agree. I guess what we actually don't want are methods for the leaves of the config tree? We probably still want |
This is done in master... |
Since
Layer
is the main interface, it would be nice if tab completion on the object only listed relevant pieces of the API so that you can quickly find what plot types are available (e.g.point()
,bar()
,text()
, etc.)Currently, since it derives from
BaseObject
the namespace is polluted with all sorts of traitlet stuff that the user probably doesn't care about.I'd propose something like this:
The only problem would be if we ever want to pass
Layer
to some other class this would complicate things. What do you think?The text was updated successfully, but these errors were encountered: