# How to draw a 3d structure using 3d coordinates from pdb file?

I am trying to create a 3d structure from 3d coordinated from a pdb file.

I am trying to draw 3d coordinates from pdb file "ATOM 1 N VAL A 14 22.692 -27.591 -39.402" and using webgl javascript.

I've managed to get the 3d coordinates from a pdb file but i don't know the exact logic that is used to create 3d structure from the coordinates found in pdb file.

I tried those coordinates and managed to create a cloud of 3d points but it is not anywhere near the structure that is found on pdb site.

So wondering how the structure is created on the pdb website?

– Mr_Z
Apr 3 at 7:29

JSmol sounds like what you want - it'll let you display 3D structures from PDB files onto webpages using JavaScript. If you just want to view the structure rather than display them on webpages, there's many programs that exist already like Swiss-PdbViewer and Pymol. There's even web-interfaces that let you upload a PDB file and they display it for you like Jena3D Viewer.

If you want to share a PDB file, you could try Michelanglo. It allows you to upload a PDB file (among other things) edit a description panel (which can feature special links that control the protein view and representation) and share the link with whomever —without needing any installations on either side. Here is the page of shared protein: gallery (disclaimer: I am the admin).

If you are interested in implementing a molecular viewer on your site, I'd suggest NGL. The PDB website uses NGL too, but is recently switching to MOL* ("molstar"), which is a new development, so less documented, but fixes some corner cases and is marginally faster and is a collaboration with a PDBe. NGL does not depend on any technology that will be depracated mind you, so it actually is a very solid choice for a JS molecular viewer.

The PDB format is a working format, not a deposition format, as is mmCIF. As a result NGL and Mol* have some issues when it comes to PDB files, such as lack of secondary structure records (HELIX/SHEET) results in anaemic sheets, fancier linkages (LINK/SSBOND reconds) are not handled only CONECT records.

• disclaimer: I am the admin ..... I though you were the creator (!!) of Michelangelo ? Apr 8 at 11:42
• @pippo1980 Ops. Yes, I am: I was trying to be subtle, but at the same time abiding by the transparency rules/guidelines/custom of SO. Apr 8 at 11:53
• I had a look at Michelanglo and as a third party I can say that it rocks !!!! Very nice tool indeed Apr 8 at 11:54
• Thank you —that is always nice to hear! Apr 8 at 12:01

As others said, there already exist javascript libraries to visualize a protein. The most complete and recent one would probably be Mol*, which is what is used on RCSB PDB website. Mol* actually works using NGL, a WebGL engine. But probably the oldest library used on RCSB PDB to visualize proteins would be JSMol. You can actually switch between these viewers on RCSB PDB 3D view using "Select a different viewer" in the bottom right (try it out on 1UBQ)

Now to address the first exercise: there are several things going on after getting the atom coordinates. A PDB file may or may not contain a CONECT part, where bonds between atoms will be clearly stated (contrarily to a CIF file which I believe always contain the bonds). Henceforth these packages may or may not have to guess atom bonds. Given that a PDB file also contains the residues of each atom it's fairly easy to do, less so when dealing with small molecules.

However what you see most of the time is a cartoon representation of proteins, where each secondary structure is represented differently. The library will compute the secondary structure of each residue based on the dihedral angles of the backbone, then represent them. As of why they look like this, check the work of Irving Geis and Jane Richardson.

So if you want to have a website showing protein structures I would strongly advise to use an already existing library, although the exercise of coding your own can always be interesting. If you want to visualize structures on your own computer without using a web interface I can only recommend PyMOL, VMD and ChimeraX.

I am not good as you are and needed to use a parser for the pdb file

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Nov  7 17:40:03 2020

@author: Pietro

"""

import matplotlib.pyplot as plt  #matplotlib

import numpy as np #numpy

openz = open('./1msc.cif')

print('opened')

# Initialize a PdbxReader object with the input file handle

# Initialize a list to be propagated with DataContainer (and/or DefinitionContainer) objects (of the DataContainer class, which inherits from ContainerBase) parsed from the CIF file, where data blocks map to DataContainer objects

data = []

print(data)

print ('data ###################################################################\n' , data)

print('data lenght' , len(data))

# Your list is now propagated with one or more DataContainer objects, which represent data blocks. To get the first data block, just use list notation:

block = data[0]

print(' block ##############################################################\n',block)

pippo=block.getObjNameList()

print(pippo)

# To retrieve a category object, use the getObj(self, name) method

atomsite = block.getObj("atom_site")

print('atom site : ', atomsite)

atom = atomsite.getValue("group_PDB",0)

# print('atom sites id :', atom)

atomlist=[]

i=0
while True:
atom =  atomsite.getValue("group_PDB",i)
atomid = atomsite.getValue('label_atom_id',i)
if atom =='ATOM':
# print(atomsite.getValue("group_PDB",i))
if atomid == 'CA':                         #select only carbon alpha (CA) to work with

atomlist.append([float(atomsite.getValue('Cartn_x',i)),\
float(atomsite.getValue('Cartn_y',i)),float(atomsite.getValue('Cartn_z',i))])

i +=1
else:
print('loop ends')
False
break

atomlist=np.array(atomlist)

print('end')

print(atomlist)

print('lunghezza : ', len(atomlist))

fig = plt.figure()
ax = plt.axes(projection="3d")

for p in atomlist:       #print CA as dots
ax.scatter3D(p[0], p[1], p[2])
print(p)

for i in range(0,len(atomlist)-1):   #connect with a line CA n with n+1
x,y,z = [atomlist[i+1][0],atomlist[i][0]],[atomlist[i+1][1],atomlist[i][1]],[atomlist[i+1][2],atomlist[i][2]]
ax.plot(x,y,z, color='red')

plt.show()