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

Usage questions about nglview: Please ask here first [1] #785

Closed
hainm opened this issue Apr 22, 2019 · 258 comments
Closed

Usage questions about nglview: Please ask here first [1] #785

hainm opened this issue Apr 22, 2019 · 258 comments
Labels

Comments

@hainm
Copy link
Collaborator

hainm commented Apr 22, 2019

For any questions relating to how/why/ ... Or anything you don't know where to ask.
For bug, suggestion, ... please open seperate issue

PS: QA-0: #589

@njbruce
Copy link

njbruce commented Apr 25, 2019

If I create a sphere with eg:

view = nglview.NGLWidget()
view.shape.add_sphere([0.0, 0.0, 0.0], [0,0,1], 10.0)

is there a way of setting the opacity of the sphere?

Thanks in advance!

@hainm
Copy link
Collaborator Author

hainm commented Apr 25, 2019

hi, there's no API yet. But you can try with below code (using the latest version).

shape

shape.ipynb.txt

@hainm
Copy link
Collaborator Author

hainm commented Apr 25, 2019

ah, there's actually an API for it but you have to play with it with more complicated case (mixing structure, shape, ...).

shape1

@njbruce
Copy link

njbruce commented Apr 26, 2019

ah, there's actually an API for it but you have to play with it with more complicated case (mixing structure, shape, ...).

Great, thanks!

@jbloom
Copy link

jbloom commented Apr 28, 2019

I'm trying to figure out the best way to set the orientation. Here is my current procedure. It works. However, can you let me know if this is indeed the best way. The reason that I wasn't sure is that it uses two private methods:

  1. Manually set the orientation to whatever I want by rotating the object.

  2. Get that orientation (as a 16-number list) with:

        mat = view._camera_orientation
    
  3. In the future, set that orientation with:

       view._set_camera_orientation(mat)
    
  4. If I want to make sure it is also centered, call:

      view.center()
    

@hainm
Copy link
Collaborator Author

hainm commented Apr 28, 2019 via email

@hainm
Copy link
Collaborator Author

hainm commented Apr 29, 2019

view._set_camera_orientation(mat)

@jbloom I've checked and we should use view.control.orient(...) function.

view.control.orient(mat) # from view._camera_orientation

@mktonycho
Copy link

mktonycho commented May 14, 2019

Hi everyone,
I am using gro and xtc files from gromacs and visualize them using nglview within Jupyter notebook.
It is unclear why rendered and downloaded images from nglview package contain white slits as you may be able to notice them on the second picture. It's not too big of a problem. Thank you for your help in advance!

The version of packages is as follows:
nglview version = 1.1.9
mdanalysis version = 0.19.2

nglview_prob

@jbloom
Copy link

jbloom commented May 14, 2019

I also had @mktonycho's problem with vertical lines, although they go away if I use antialias=True with render_image.

@hainm
Copy link
Collaborator Author

hainm commented May 14, 2019 via email

@hainm
Copy link
Collaborator Author

hainm commented May 14, 2019

It is unclear why rendered and downloaded images from nglview package contain white slits as you may be able to notice them on the second picture. It's not too big of a problem.

@mktonycho should be fixed in master branch (by upgrading to NGL 0.36).

@mktonycho
Copy link

@jbloom @hainm Thank you so much for your help!!! I will try again with the new version!

@rasmusthog
Copy link

Hi! Not sure if this should be submitted as a separate issue, or if there is something I'm not doing correctly that can easily be fixed on my side.

I'm trying to run nglview in a Jupyter Notebook through ASE using nglview.show_ase(atoms) where atoms is the ASE Atoms-object I want to view.

When I make this call, I get a permission error is thrown (pasted below).

Appreciate any help I can get here.


PermissionError Traceback (most recent call last)
in
----> 1 nglview.show_ase(co)

C:\Anaconda3\lib\site-packages\nglview\show.py in show_ase(ase_atoms, **kwargs)
84 """
85 structure = ASEStructure(ase_atoms)
---> 86 return NGLWidget(structure, **kwargs)
87
88

C:\Anaconda3\lib\site-packages\nglview\widget.py in init(self, structure, representations, parameters, **kwargs)
201 else:
202 if structure is not None:
--> 203 self.add_structure(structure, **kwargs)
204
205 if representations:

C:\Anaconda3\lib\site-packages\nglview\widget.py in add_structure(self, structure, **kwargs)
1089 raise ValueError(
1090 f'{structure} is not an instance of Structure')
-> 1091 self._load_data(structure, **kwargs)
1092 self._ngl_component_ids.append(structure.id)
1093 if self.n_components > 1:

C:\Anaconda3\lib\site-packages\nglview\widget.py in _load_data(self, obj, **kwargs)
1196 if not is_url:
1197 if hasattr(obj, 'get_structure_string'):
-> 1198 blob = obj.get_structure_string()
1199 kwargs2['ext'] = obj.ext
1200 passing_buffer = True

C:\Anaconda3\lib\site-packages\nglview\adaptor.py in get_structure_string(self)
102
103 def get_structure_string(self):
--> 104 return _get_structure_string(self._ase_atoms.write)
105
106

C:\Anaconda3\lib\site-packages\nglview\adaptor.py in _get_structure_string(write_method, suffix)
29 def _get_structure_string(write_method, suffix='.pdb'):
30 with NamedTemporaryFile(suffix=suffix) as fh:
---> 31 write_method(fh.name)
32 return fh.read().decode()
33

C:\Anaconda3\lib\site-packages\ase\atoms.py in write(self, filename, format, **kwargs)
1852 """
1853 from ase.io import write
-> 1854 write(filename, self, format, **kwargs)
1855
1856 def iterimages(self):

C:\Anaconda3\lib\site-packages\ase\io\formats.py in write(filename, images, format, parallel, append, **kwargs)
380 io = get_ioformat(format)
381
--> 382 _write(filename, fd, format, io, images, parallel=parallel, append=append, **kwargs)
383
384

C:\Anaconda3\lib\site-packages\ase\io\formats.py in _write(filename, fd, format, io, images, parallel, append, **kwargs)
411 if append:
412 mode = mode.replace('w','a')
--> 413 fd = open_with_compression(filename, mode)
414 io.write(fd, images, **kwargs)
415 if open_new:

C:\Anaconda3\lib\site-packages\ase\io\formats.py in open_with_compression(filename, mode)
306
307 if compression is None:
--> 308 return open(filename, mode)
309 elif compression == 'gz':
310 import gzip

PermissionError: [Errno 13] Permission denied: 'C:\cygwin64\tmp\tmp7fatov62.pdb'

@hainm
Copy link
Collaborator Author

hainm commented May 29, 2019

hi @rasmusthog, you can do either

  • make sure your C:\cygwin64\tmp writable by python
  • patch the get_structure_string function to write file to your current folder.

something like

def get_structure_string(self):
    print("HELLO")
    fname = 'tmp.pdb'
    self._ase_atoms.write(fname)
    with open(fname) as fh:
        return fh.read()
    
nv.adaptor.ASEStructure.get_structure_string = get_structure_string

@jaygn
Copy link

jaygn commented May 29, 2019

Hi,

I'm trying to get nglview up and running and I'm probably overlooking something simple...

I created an environment with conda and installed juypter, pytraj and nglview. Everything installed smoothly. When I run the tutorial, I see the expected output from the first cell (nglview version = 1.1.7, pytraj version = 2.0.4)

However, after the third cell, (view._display_image()), I get a broken image icon. I tried running the same command sequence in ipython and got <IPython.core.display.Image object> as the output, but again, no image. I've tried with both python 2.7 and 3.7, both locally and remotely, and with the tutorial files and my own and I get the same behavior in all scenarios. The notebook is running on ubuntu 18.04.

Thanks for your help

@hainm
Copy link
Collaborator Author

hainm commented May 29, 2019

@jaygn Please post your screenshot.
(But I guess you have to run render_image and _display_image in different cell, make sure there's a small delay between commands).

But you can try the latest version via (v2.1.0), you can see the rendered image without using _display_image.

example: #808

@jaygn
Copy link

jaygn commented May 29, 2019

Thanks @hainm. Here's the screenshot. I tried both with render_image and _display_image in the different and the same cells. I get the same behavior when I run the tutorial notebook in place or if I copy the commands to a new notebook and run it there.

Screen Shot 2019-05-29 at 12 54 10 PM

I tried updating to 2.1.0 and I still don't see the image, although now it's trying to display after the render_image step as you said.

Screen Shot 2019-05-29 at 1 07 35 PM

@hainm
Copy link
Collaborator Author

hainm commented May 29, 2019

sorry for your inconvenience. Can you try

  • close your notebook
  • activate nglview-js-widgets (I've heard that you don't need that with the latest notebook, not sure)
jupyter-nbextension install nglview --py --sys-prefix
jupyter-nbextension enable nglview --py --sys-prefix
  • open your notebook and try again.

@jaygn
Copy link

jaygn commented May 29, 2019

That worked! It looks great now. Thanks so much for the prompt help!

@hainm
Copy link
Collaborator Author

hainm commented May 29, 2019

thanks for trying.

@rasmusthog
Copy link

Thanks, @hainm!

I have now modified the permissions (changed the ownership of the tmp-folder to my user instead of the local Administrator account), but I'm still getting the same error. Also tried changing the permissions so that the tmp-folder is globally readable (chmod -R 777), but still the same result.

This is how the folder looks from a ls -l:

drwxrwxrwx+ 1 [my username] [computer name]+None 0 May 30 10:27 tmp

@hainm
Copy link
Collaborator Author

hainm commented May 30, 2019

sorry @rasmusthog that I can't not help further with the permission error because I don't have any windows machine to test (I am mainly working with linux and macos). But please try the patch I mentioned. cheers.

@garyo
Copy link

garyo commented May 31, 2019

I'm embedding NGL. I'm loading a model like this (in an async typescript function):

  let obj = await stage.loadFile(name, { defaultRepresentation: false })
  obj.setDefaultAssembly('BU1') 
  representations.forEach((elt, idx) => {
    obj.addRepresentation(elt[0] as NGLViewer.StructureRepresentationType, elt[1])
  })
  obj.autoView()

but when I dump the Three.js scene (stage.viewer.scene) immediately after this, the graphics objects don't exist yet. I think they're getting created in the background.
Is there any callback or hook so I can know when the world is fully loaded?

@hainm
Copy link
Collaborator Author

hainm commented May 31, 2019

@garyo
Copy link

garyo commented May 31, 2019

Thanks for the example -- but I don't see there how to invoke a callback once all the graphics objects are loaded. If you dump the scene at the end of that example, just after o.autoView(), it will not have any meshes. Actually in your simple example it may, but if you use a 'surface' representation or something else that requires a bg task to compute, it won't be there yet.

@garyo
Copy link

garyo commented May 31, 2019

Looking at the source, in representation.ts representation.make() takes an optional callback to call when it's done, but nobody calls it with a callback arg as far as I can see.

@oliverdutton
Copy link

oliverdutton commented Apr 1, 2021

Hi, so this does work perfectly for me and is how I usually do it.

Doing it this way involves:

  • construct the visualisation
  • display it
  • wait an uncertain amount of time for the whole visualisation to load
  • then write it out

Is there some command I can use to block until the visualisation has fully loaded?

otherwise each visualisation is requiring my oversight, I can't batch make 100 at once.

@wangfan860
Copy link

Hello! Thanks for the great tool! I have a question about the jupyter notebook to html conversion. The images didn't show in the exported html. Is there a way to display the images within the whole notebook as a html? Thanks in advance !!😄

@hainm
Copy link
Collaborator Author

hainm commented May 4, 2021

. The images didn't show in the exported html. Is there a way to display the images within the whole notebook as a html? Thanks in advance !!😄

hi @wangfan860 unfortunately No.

You can use nv.write_html to export a single view for that. #687

@CalCraven
Copy link

I'm having a problem loading a .gsd and a .dcd file though MDAnalysis and visualizing with nglviewer. No matter what representation I use with the Widget object, I cannot get rid of the bonds between the atoms in my system (there should be none). My MDAnalysis Universe has no bonds, but the Widget shows connections between all of the atoms. I'm also having trouble based on the naming conventions of my system (it's course grained, so all atom names start with '_'), and cannot change the color of each of the two atom types individually. If anyone knows a good way to overwrite my atom names to something more easily recognized by nglview, that would be great.

import nglview as nv
import MDAnalysis as mda

U = mda.Universe( 'bulk.gsd', 'trajectory_bulk_chi0.dcd')

for atom in U.atoms:
    if atom.name == 'cg_A':
        atom.residue.resname = 'RES'
        atom.name = 'A'
    else:
        atom.residue.resname = 'RES'
        atom.name = 'B'

print(U.bonds)

view = nv.show_mdanalysis(U)
view.add_representation('ball_and_stick', selection='.A', color='red')
view.add_representation('ball_and_stick', selection='.B', color='blue')

view

python=3.7
nglview=3.0.3
mdanalysis=2.0.0

![image](https://user-images.githubusercontent.com/54594941/139150554-53c32e08-b259-4ea1-904d-b5bf63cef591.png
nglview_tests.zip
)

@markperri
Copy link

I'm trying to select a residue in my trajectory (loaded from NAMD). I have numeric residue names and I think it's causing problems using masks. Is there a way around this?

print(set(residue.name for residue in _traj.top.residues))
{'TIP3', '000'}
residueList = traj.top.select(':000')
residueList
Error: One or both numbers of mask arg (000) < 1 (0, 0)
Error: Could not parse mask [:000].

python version: 3.9
nglview version: 3.0.3
ipywidgets version: 7.6.3

Thanks,
Mark

@hainm
Copy link
Collaborator Author

hainm commented Jan 12, 2022

I'm trying to select a residue in my trajectory (loaded from NAMD). I have numeric residue names and I think it's causing problems using masks. Is there a way around this?

print(set(residue.name for residue in _traj.top.residues))
{'TIP3', '000'}
residueList = traj.top.select(':000')
residueList
Error: One or both numbers of mask arg (000) < 1 (0, 0)
Error: Could not parse mask [:000].

python version: 3.9 nglview version: 3.0.3 ipywidgets version: 7.6.3

Thanks, Mark

hi @markperri: Is your question about pytraj or nglview? If it's about pytraj, please open a new issue in pytraj repo: https://github.com/Amber-MD/pytraj/discussions

@markperri
Copy link

hi @hainm, oh you're right, sorry for the mixup!
Mark

@hainm
Copy link
Collaborator Author

hainm commented Jan 12, 2022

@markperri

you can watch this thread: Amber-MD/cpptraj#930

@atygesen
Copy link

atygesen commented Mar 4, 2022

Hi - I was wondering if there is an easy way of changing the element in a pre-existing view - i.e. to interactively change elements, without having to remake the entire widget?

@hainm
Copy link
Collaborator Author

hainm commented Mar 4, 2022

Hi - I was wondering if there is an easy way of changing the element in a pre-existing view - i.e. to interactively change elements, without having to remake the entire widget?

What do you mean about "elements"? Are they "components" in nglview terms?
If yes, please use view.remove_component
https://github.com/nglviewer/nglview/search?q=remove_component

@atygesen
Copy link

atygesen commented Mar 4, 2022

I guess you could say components. More specifically, I'm adding/removing individual atoms from an ASE trajectory, starting from 1 full atoms object, and then replacing single sites.

I guess one option is to draw each atom in the entire atoms object as 1 component, and then add/remove them individually like that.

@hainm
Copy link
Collaborator Author

hainm commented Mar 4, 2022

More specifically, I'm adding/removing individual atoms from an ASE trajectory, starting from 1 full atoms object, and then replacing single sites.

Oh, I don't think nglview could handle this. Your option is on track.

@atygesen
Copy link

atygesen commented Mar 4, 2022

Well - slightly on extension of this, how would you force an update? Say I make some changes to my components, and then do a time.sleep(2), nglview isn't updating during that downtime. Can I forcefully trigger it to update my widget?

@hainm
Copy link
Collaborator Author

hainm commented Mar 4, 2022

@atygesen nglview does not natively support changing component's topology, only coordinates. To do that, you need to call replaceStructure

Please see this: #589 (comment)

@hainm
Copy link
Collaborator Author

hainm commented Mar 4, 2022

@atygesen nglview does not natively support changing component's topology, only coordinates. To do that, you need to call replaceStructure

Please see this: #589 (comment)

and here:

@YoelShoshan
Copy link

Hi!
Is there some example on how to super(im)pose two structure (ground truth and a prediction) to compare them?

@hainm
Copy link
Collaborator Author

hainm commented Dec 11, 2022

Hi! Is there some example on how to super(im)pose two structure (ground truth and a prediction) to compare them?

dear @YoelShoshan,

Assume you have two components in your view

view.add_structure(...) # 1st
view.add_structure(...) # 2nd
view._js("""
this.superpose(0, 1, True, asl1, asl2) 
""")

replace asl1 and asl2 by your atom selection from first and 2nd components.
Here is the code in Javascript that Python calls: 

superpose(cindex0, cindex1, align, sele0, sele1) {
// superpose two components with given params
var component0 = this.stage.compList[cindex0];
var component1 = this.stage.compList[cindex1];
component1.superpose(component0, align, sele0, sele1);
}

@YoelShoshan
Copy link

YoelShoshan commented Dec 12, 2022

@hainm Thank you very much!
I'm still missing something basic, let's ignore the superposition logic for a moment, and say I just want to show 2 structures.

Please see the following small code reproducing my issue:

### imports
from Bio.PDB import * 
import gzip
import nglview as nv
from copy import deepcopy

### load the protein
debug_pdb_id = '7cg5'
mmcif = f'/some/path/{debug_pdb_id}.cif.gz'
print(f'loading: {mmcif}')
parser = MMCIFParser()
with gzip.open(mmcif, 'rt') as fh:
    ref_structure = parser.get_structure(debug_pdb_id, fh)

###clone it and shift all atoms:
pred_structure = deepcopy(ref_structure)
chain = list(pred_structure.get_chains())[0]
residues = list(chain.get_residues())
atoms = list(residues[10].get_atoms())
for a in atoms:
    a.set_coord([x+1.0 for x in a.get_coord()])
    
### try to visualize it (see exception details below)
view = nv.NGLWidget()
view.add_structure(ref_structure) ### here I get an exception: "ValueError: <Structure id=7cg5> is not an instance of Structure" 
view.add_structure(pred_structure)
view    

is there a certain way I should wrap/convert the structure instance that I get from MMCIFParser for nglview to recognize it?
Or any other approach you recommend?
Ideally I prefer to do this "on the fly" without writing any files.

@hainm
Copy link
Collaborator Author

hainm commented Dec 12, 2022

is there a certain way I should wrap/convert the structure instance that I get from MMCIFParser for nglview to recognize it?
Or any other approach you recommend?
Ideally I prefer to do this "on the fly" without writing any files.

Is that Biopython's object? If so, you can try below

ref = nv. BiopythonStructure(ref_structure)
view.add_structure(ref)
# so on for pred_structure

@YoelShoshan
Copy link

@hainm works perfectly, thanks!

@YoelShoshan
Copy link

view.add_structure(...) # 1st
view.add_structure(...) # 2nd
view._js("""
this.superpose(0, 1, True, asl1, asl2)
""")

Another question - what are reasonable values for asl1 and asl2 ?
how is it expressed? indices?
what if:

  1. I want an all-atom superposition
  2. I want a Ca based superposition

What are reasonable values to use and what is the format ?

@hainm
Copy link
Collaborator Author

hainm commented Jan 12, 2023

view.add_structure(...) # 1st
view.add_structure(...) # 2nd
view._js("""
this.superpose(0, 1, True, asl1, asl2)
""")

Another question - what are reasonable values for asl1 and asl2 ? how is it expressed? indices? what if:

  1. I want an all-atom superposition
  2. I want a Ca based superposition

What are reasonable values to use and what is the format ?

asl1 and asl2

I think they use NGL's selection language here. Please have a look: https://nglviewer.org/ngl/api/manual/usage/selection-language.html

@citi0
Copy link

citi0 commented May 19, 2024

Thanks everyone and @arose
What is the syntax for using distance in the nglviewer? (I have tried various ways to specificy the atoms needed for the measurement but have not found the correct way to do that by a trial and error approach)
I can use the cotrol nad click method but would like to use the distance wrapper to vary the display of th emeasurements

@LijieZhong
Copy link

  • Version report
python -c 'import nglview; print(nglview.__version__)'
3.1.2
!python -c 'import ipywidgets; print(ipywidgets.__version__)'
8.1.2
from ase.io import read,write
import nglview as ngl
data = read("./)pro.gro")
vis = ngl.show_ase(data)
vis
![stru](https://github.com/nglviewer/nglview/assets/64005198/aed437d9-c18f-44cc-8478-eb49b5a221ff)

Hello, I am trying to view a mixed solvent system using the above code, but the lithium ions in this system do not seem to display properly, how should I solve this problem
Thanks

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