-
-
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
Allow working with Renderers interactively outside the notebook #1214
Conversation
Looks good to me. I guess you've tested that there aren't problems with getting the wrong backend in the notebook after this? |
holoviews/plotting/bokeh/renderer.py
Outdated
@@ -146,4 +162,6 @@ def load_nb(cls, inline=True): | |||
""" | |||
Loads the bokeh notebook resources. | |||
""" | |||
import matplotlib.pyplot as plt | |||
plt.switch_backend('agg') |
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.
Need to remove this.
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.
In the bokeh backend??
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.
Right, hence why I need to remove it.
@philippjfr , I'm willing to test - but how should I get it installed using conda? |
Don't necessarily recommend this but you could: conda uninstall holoviews
pip install https://github.com/ioam/holoviews/archive/mpl_interactive.zip Then later you can switch back to a conda based dev release with: pip uninstall holoviews
conda install -c ioam/label/dev holoviews |
But note that using the git version of holoviews isn't particularly difficult; just conda install as normal then clone this repository, do |
If a user wants to go back to the conda versions (dev or otherwise) after running I'm sure I have dealt with this myself before but either I'm having a mental blank or the answer isn't totally obvious. :-) |
Deleting the git repo is sufficient. develop just adds a path file, and Python moves on to the next item in the path (presumably the conda envt) when the git repo isn't found. |
I usually end up deleting files in the envs site-packages manually, because I don't trust the interaction between pip/conda/setuptools. |
What's wrong about the aspect? In both examples the axis ranges are of equal range so even if you enabled
Right, those are annoying me quite a bit now, they've been fixed in matplotlib master a while back but for some reason those fixes didn't make it into 2.0. I'll have another look at avoiding them. |
Does running a |
No it doesn't close it - once you close the first one - second appears.
Wrong aspect for the figure window - not for the plot in it. from matplotlib import pyplot
pyplot.plot(range(10))
pyplot.show() I guess it's the way how matplotlib handles the figure size and plot aspect in that figure... |
Essentially figure should inherit the plot's aspect ratio. |
Thanks for clarifying I'll have to look into that. |
I'll look into that as well. I'm probably revealing my unfamiliarity with interactive use of matplotlib here, but is there any reason why it shouldn't just always "hold" figures letting you display multiple at once? |
I think it's due to the defaults from Matlab... |
bb972c8
to
9cdd3f8
Compare
In interactive mode you don't actually need to call import numpy as np
import holoviews as hv
import holoviews.plotting.mpl
r = hv.Store.renderers['matplotlib'].instance(interactive=True)
curve = hv.Curve(range(10))
r.show(curve)
image = hv.HoloMap({i: hv.Image(np.random.rand(10,10)) for i in range(10)})
plot = r.show(image)
plot.update((2,))
|
I tested it. What I did:
Got only aspect warnings. Then started ipython and run it like this:
Again, got only warnings and no figures. Then did this in the new ipython kernel:
And it worked (except for aspect issue). So I would say that the version before this one worked better for me (cause it worked outside of ipython). @philippjfr , may I add one more thought into consideration? |
Sorry we've been misunderstanding each other, import numpy as np
import holoviews as hv
import holoviews.plotting.mpl
r = hv.Store.renderers['matplotlib']
curve = hv.Curve(range(10))
img = hv.Image(np.random.rand(10,10))
r.show([curve, img, curve+img])
The main difference is that holoviews objects themselves are not plots they are simply your data with some metadata. The notebook provides hooks to automatically transform the objects containing your data into a visual representation. Outside the notebook context you unfortunately need a bit of boilerplate to turn the objects into plots. In matplotlib you also have to initialize your backend (e.g. Let me know what you think of the new approach above, I do want to make the transition between notebook and scripts as smooth as possible, without adding unnecessary boilerplate. |
Note I haven't figured out the aspect issues yet, so you saw those in Qt4? |
I did consider this when originally implementing the notebook extension and perhaps we should consider finding a better solution here, specifically around importing the backend. At minimum we might be able to let |
Unless |
Yes, that makes sense, I thought it might return all initialized renderers, which would be awkward but returning the active renderer makes sense. It does clutter all cells that end in |
Why don't you let people to set some env. variables to control default bahaviour. That would include back-end, Jupyter v.s. standalone, output format and etc. Then |
I'd rather not use envt variables if at all possible; that's a clunky way to do it. Good point about the values that would get printed in the notebook; output_notebook does indeed often end a cell at present, mainly because of the logo/message it prints (which I've voted to get rid of anyway :-). In that case, you're right; probably better not to return anything by default. I suppose one could have an argument that would enable such returns, but that too is a bit clunky. |
A clean way? I don't consider checking the type of I don't think using What I would be open to is an equivalent for pure Python users, e.g |
I just thought a little bit more about it and actually would say that adding a global feature like ##%%writefile test.py
import holoviews as hv
from my_hv_objects import myDataCurve, myDataImage
if __name__=="__main__":
hv.rc.standalone=True
myDataCurve()
myDataImage() And for interactive/html ##Jupyter
from test import myDataCurve, myDataImage
myDataCurve()
myDataImage() But for standalone simple python test.py or in ipython
would do the trick |
Another idea is to create |
If you're willing to go down that route it seems to me like you would actually be better served by generating HTML reports from your notebooks directly using nbconvert. How does that sound? |
@philippjfr I can generate HTML reports right now - but that's not sufficient. What I'm trying to help my users with is this:
The thing is to minimize manual work need to be done from step 1 to step 2. Currently users use matplotlib most of the time and then just copy-paste all the stuff to the standalone script. If they have any bokeh or plotly - they keep it for further R&D in the notebook - but drop them from converting to standalone script or reimplement some pieces of it using matplotlib. I can instantly see how useful holoviews can be for this workflow. |
Interesting. That's not a workflow that I would use personally, because to me a notebook is much more of a shareable thing than a script is, because it can include interleaved Python, descriptions, and output, where it's possible to tell a story that other people can read and understand. And here HoloViews helps greatly in making a notebook that can tell a story, as opposed to a notebook crammed with unreadable plotting code -- it should all be readable! But maybe I'm missing the point of the standalone script, when used with HoloViews. |
I agree with you on notebooks - but that's not all what people do. Matplotlib code can be reused in standalone world - holoviews in it existing form can't. Essentially we are using Jupyter not for final presentation or report only. We are using it in order to develop ideas - but we are not deploying through it - it's inefficient at least in the sense that other users would need to know Jupyter, start the server with all dependencies and be able to run it with their data. Instead we build a standalone script which looks and feels like any other C/C++/Fortran program and users don't even notice that they run python.... Regardless of all what I have said - holoviews is very promising product - but limiting it to Jupyter only or complicate transition to standalone is waste of potential. |
I've been dreaming about holoviews all these years - just never realized that. I'll share with you one quite standard notebook soon which is generated based on one of my user's Matlab code - and I honestly don't even think that it's possible to be done in holoviews.... I wonder how difficult it would be to build a holoviews code generator based on existing matplotlib figure? |
79f7446
to
986cdf3
Compare
With the release of 1.7 coming up I'm going to suggest we merge this as is and can consider how we can make it easier yet. For now this makes it possible to use the matplotlib backend from scripts and in interactive mode in an IPython terminal, which wasn't allowed before. Since bokeh ships facilities to open a bokeh plot in a browser I'm not going to duplicate this in a I'll keep the corresponding issue open to keep the discussion open and at minimum remind us to add documentation. |
I agree with Philipp. We may still find a better approach but this PR does go a long way towards the requested functionality. I do think it will really help with any HoloViews usage outside the notebook. Merging. |
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. |
Adds
show
methods for the bokeh and matplotlib renderers and an interactive option for the matplotlib renderer. Addresses #1126. @thoth291 would you mind testing if this works for you?Here's a small example: