Skip to content
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

[py3dmol BUG] p.getView() does not return an array that could be used with p.setView(). #599

Closed
ajasja opened this issue May 23, 2022 · 11 comments
Labels

Comments

@ajasja
Copy link

ajasja commented May 23, 2022

Describe the bug
p.getView() does not return an array that could be used with p.setView().

To Reproduce
https://colab.research.google.com/drive/1MNCej1_Ih6b1E_Ky4UHP7eRt8pr3_4-S?usp=sharing

p = py3Dmol.view() # Notice the tuple here
p.addModels(pdb_str, "pdb")
p.setStyle({'cartoon': {'color':'spectrum'}})
p.getView() #I would expect to get a transformation matrix here

Expected behavior
According to the docs an array should be returned, but a viewer instance is returned.

image

What is returned in py3dmol
image

@ajasja ajasja added the bug label May 23, 2022
@ajasja ajasja changed the title [py3dmol BUG] [py3dmol BUG] p.getView() does not return an array that could be used with p.setView(). May 23, 2022
@dkoes dkoes added wontfix and removed bug labels May 23, 2022
@dkoes
Copy link
Contributor

dkoes commented May 23, 2022

All communication between python and 3dmol is one-way by design (there is no need to have an active python kernel for 3dmol.js to work, which means notebooks can be shared as webpages).

This is the intended behavior.

@dkoes dkoes closed this as completed May 23, 2022
@ajasja
Copy link
Author

ajasja commented May 23, 2022

Thanks for the quick feedback! Let me then state what I'm trying to do:
I'm using PyRosetta to generate a parametric backbone interactively.
For that I'm using interact (and ipywidgets).

However every time a slider is changed, the viewpoint get's reset.
Is there a way around that?
https://colab.research.google.com/drive/1naxbOoeUrAfGhOpwJhMOlItCrcT9CKAN?usp=sharing

@dkoes
Copy link
Contributor

dkoes commented May 23, 2022

I can't run this, even when I give it access to Google Drive (which I'm not thrilled about), so I can only guess at the issues.

py3Dmol works by writing javascript out to the page. colab sandboxes every output cell so it can't access javascript objects in other cells (outstanding issue #550).

I suspect a new viewer is being created everytime you interact with the viewer object via interact. It is possible running p.update() will resolve the problem, but if the issue is that object is being sandboxed (meaning the previously created viewer isn't visible to the code that is currently running) then I'm not sure what can be done.

@dkoes
Copy link
Contributor

dkoes commented May 23, 2022

(You should check the behavior in a local Jupyter notebook which doesn't sandbox cells).

@ajasja
Copy link
Author

ajasja commented May 23, 2022

Thanks! I'm preparing a workshop on protein design, where my students will use Google colab, so optimally it should wok in colab.
That said, in the jupyter notebook the behaviour is the same (the view get's reset). I was thinking if I can get the viewing matrix to python using some javascript magic, then I could solve this problem. But I might just give up and call it good enough:)

Would it help if I made a simpler example that does not require the huge PyRosetta package?

PS: I forgot to say this before, but py3dmol is absolutely amazing! And without it an interactive protein design workshop would be much more boring and harder to organize (people would have to install pymol and then download the files to look at them etc).

@dkoes
Copy link
Contributor

dkoes commented May 23, 2022

Yes, a minimal test case would be great.

@ajasja
Copy link
Author

ajasja commented May 24, 2022

@dkoes Hi, here is minimal test case:
The assumption is that I'm generating backbones parametrically and there are too many to load into the viewer ahead of time.
If I drag the slider (and the view is from the top), then everything works as intended. However if I rotate the bundle a little bit and want to see how the parameters affect the bundle from the side, then the view gets reset every time.

https://colab.research.google.com/drive/1aSjw6yaRLUF7xYSwzAmv8twzqTro_sO_?usp=sharing

@dkoes
Copy link
Contributor

dkoes commented May 24, 2022

You need to avoid instantiating another viewer, which is what is happening each time make_animation_bundle is called. Instead, create and show the viewer once, and then call update within the interactive widget. All these needs to be in the same cell in colab.

p = py3Dmol.view()
view_field = p.getView()
p.setStyle({'cartoon': {'color':'spectrum'}});
print(view_field)
p.show() #only instantiate the viewer once

def make_animation_bundle(r0_ang=5):
  p.removeAllModels()
  #print(f"manual_make_bundle{r0_ang:g}.pdb")
  if r0_ang==6.5:
    r0_ang = 6.6 #No idea how one pdb got the wrong name...
  with open(f"manual_make_bundle{r0_ang:g}.pdb") as f:
    p.addModels(f.read(), "pdb")
  p.setStyle({'cartoon': {'color':'spectrum'}})
  p.update() # update already instantiated viewer



r0_slider= widgets.FloatSlider(min=1, max=10, step=0.5, value=5, continuous_update=True)


output = widgets.Output()
with output:
  interactive_plot= interactive(make_animation_bundle, r0_ang=r0_slider);
  interactive_output = interactive_plot.children[-1]
  interactive_output.layout.height = '600px'
display(interactive_plot, output)

@ajasja
Copy link
Author

ajasja commented May 24, 2022

Perfect, thank you!

@benf549
Copy link

benf549 commented Oct 12, 2022

OMG thank you for this question, was trying the same thing (get/set view) to prevent the camera from resetting

@ajasja
Copy link
Author

ajasja commented Oct 12, 2022

@benf549 Since I saw you are in rosetta commons, you might also be interested in a Rosetta specific viewer built on top of py3dmol:
https://github.com/RosettaCommons/pyrosetta_viewer3d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants