-
-
Notifications
You must be signed in to change notification settings - Fork 404
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
Update Customizing Plots Docs with more description about .options #2923
Conversation
Thanks so much for going through these. Would you mind clearing the notebooks? Makes it easier/possible to review the changes and avoids bloating the repository. |
"instance", | ||
"_Feature" | ||
], | ||
"window_display": false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assume these are from various notebook extensions you have? Would you mind clearing these. Check out #1617 for a small script to do this.
"\n", | ||
"`.opts` is essentially the Python script version of `%%opts`: in both, you'll have to manually categorize whether an option is a style, plot, or norm option.\n", | ||
"\n", | ||
"Ultimately, `.options` method is preferred because using `.opts` requires extreme verbosity in nested dictionaries, which can get overwhelming fast." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small typo in form of a double space here.
These changes look great to me, just had two small comments. |
I'm having trouble with using jq to clear the notebook output (presumably because I'm using a Windows Subystem Linux). Maybe you can help me do it? I tried installing from |
For now you could just push the changes in this commit to your branch: 68b23ed Not sure what's wrong with |
I'm happy to see this merged but will give @jbednar and @jlstevens a chance to review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Here it is, again, with the `.options` method, which is the simplest way of customizing because it will automatically deduce whether an option is a style, plot, or norm option. In addition, `.options` is portable across notebook environments and `.py` scripts, and also will be saved on export, unlike `%%opts`." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does it mean to be "saved on export"? To a .py script? If so, maybe "is portable across notebook environments and .py
scripts, including exporting the notebook to a .py
file, unlike %%opts
.".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, here you need to move hv.renderer
to a subsequent cell. The %%opts
cell magic is only applied to the output of the cell, when it's displayed, not to everything in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I understand that's only applied to the output of the cell (if I wanted to do the whole notebook I believe I can do %opts).
However, my point with this statement:
also will be saved on export, unlike
%%opts`
is that when you do a renderer.save() on objects modified by cell magic, the options don't embed into the saved.html unlike using the .options()
obj = obj.options(width=1000)
hv.renderer('bokeh').save(obj, 'test2')
display(HTML('test2.html')) # this will have width = 1000 embedded in the html
So I guess to clarify, I should reword to
and also will be embbed to the export file, unlike `%%opts`."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I wasn't clear -- renderer.save() should keep all options that have been modified on the object; if it didn't, that would be a very strange bug. But the point here is that you're doing renderer.save() on an object that has not yet been modified by cell magic, which is why you are failing to see any effect. At that point, the cell magic application is still in the future! You have to do the renderer.save() after the cell has been displayed, because cell magics are applied only on the output of the cell, which hasn't yet occurred by the time you are saving it. So all of the wordings you are suggesting are incorrect; %%opts does change the object in a way that will export; you just have to make sure that (a) the object is in fact affected by the cell magic (by returning it as the output of the cell), and (b) that you don't save it until after it has been returned as the output of the cell. Does that make sense now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, thanks for clarifying! I see your point now and learned something new! I wonder if I'm the only one who encountered this before? If not maybe should have it as another FAQ?
"
Q: Why isn't my %%opts magic applied when exported?
A: You're probably doing renderer.save() on an object that has not yet been modified by cell magic, which is why you are failing to see any effect. At that point, the cell magic application is still in the future! You have to do the renderer.save() after the cell has been displayed, because cell magics are applied only on the output of the cell, which hasn't yet occurred by the time you are saving it. So all of the wordings you are suggesting are incorrect; %%opts does change the object in a way that will export; you just have to make sure that (a) the object is in fact affected by the cell magic (by returning it as the output of the cell), and (b) that you don't save it until after it has been returned as the output of the cell. Does that make sense now?
"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make it more general:
Q: Why isn't my %%opts cell magic being applied to my HoloViews object?
A: %%opts is convenient because it tab-completes, but it can be confusing because of the "magic" way that it works. Specifically, if you use it at the top of a Jupyter notebook cell, the indicated options will be applied to the return value of that cell, if it's a HoloViews object. So, if you want a given object to get customized, you need to make sure it is returned from the cell, or the options won't ever be applied, and you should only access it after it has been returned, or the options won't yet have been applied. For instance, if you use renderer.save()
to export an object and only then return that object as the output of a cell, the exported object won't have the options applied, because they don't get applied until the object is returned (during IPython's "display hooks" processing). So to make sure that options get applied, (a) return the object from a cell, and then (b) access it (e.g. for exporting) after the object has been returned. To avoid confusion, you may prefer to use .options()
directly on the object to ensure that the options have been applied before exporting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, another FAQ:
Q: Why are my .options()
settings not having any effect?
A: By default, .options()
returns a copy of your object, rather than modifying your original object. In HoloViews, making a copy of the object is cheap, because only the metadata is copied, not the data, and returning a copy makes it simple to work with a variety of differently customized versions of any given object. You can pass clone=False
to .options()
if you wish to modify the object in place.
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"When using ``.options`` to apply options directly to an individual object we do not have to explicitly declare which object the options apply to, however often it is useful to set options on a composite object. In these cases the options can be declared as a dictionary of the type name and the options. The code below is therefore equivalent to the syntax we used above:" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@philippjfr, does .options only accept a type name, or does it also accept a fully qualified type.group.label string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type.group.label
is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's what I thought. The text needs to be updated here to reflect that.
Thanks, @ahuang11!! |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Somewhat addresses #2916
This task turned out to be more difficult than I initially imagined (kudos to you guys for writing all the docs!)
There seems to be redundancy across places in the docs, and I'm not sure if it's appropriate to remove them or leave them there. Maybe it's best to wait for #2485 so it's not necessary to show other methods of customization in detail besides
.options
besides a brief mention? I think, that way, the documentation can be more straightforward and clear for the average user.(I'm not sure why the muted alpha stuff is still showing as commits if it's already merged into master).
Perhaps, it's more helpful to update the FAQ or create a cheat sheet first while the core developers can discuss the best way forward for the customization docs?