11import numpy
2+ import matplotlib .pyplot
23import pandas
34import pymol
45
@@ -319,3 +320,153 @@ def write_pymol_session(df, g):
319320
320321def quit_pymol ():
321322 pymol .cmd .quit (code = 0 )
323+
324+ def save_six_views (selection = 'all' ,
325+ prefix = 'tmp.csubst.pymol' ,
326+ width = 900 ,
327+ height = 900 ,
328+ dpi = 300 ,
329+ ray = True ):
330+ """
331+ Saves six images of the selected object from +X, -X, +Y, -Y, +Z, -Z directions.
332+ """
333+
334+ # Each direction is 18 floats:
335+ # 1) 3x3 rotation matrix = 9 floats
336+ # 2) camera position (3 floats)
337+ # 3) front, back (2 floats)
338+ # 4) perspective (1 float)
339+ # 5) origin shift (3 floats)
340+ directions = {
341+ 'pos_x' : [
342+ # Rotation: point the camera along +X => +X points "out of screen"
343+ 0.0 , 0.0 , - 1.0 , # row1
344+ 0.0 , 1.0 , 0.0 , # row2
345+ 1.0 , 0.0 , 0.0 , # row3
346+
347+ # Camera position (move camera +X):
348+ 100.0 , 0.0 , 0.0 ,
349+
350+ # front plane, back plane:
351+ 0.0 , 200.0 ,
352+
353+ # perspective (1.0 => perspective on, -1 or 0 => orthoscopic):
354+ 1.0 ,
355+
356+ # origin translation:
357+ 0.0 , 0.0 , 0.0
358+ ],
359+ 'neg_x' : [
360+ 0.0 , 0.0 , 1.0 ,
361+ 0.0 , 1.0 , 0.0 ,
362+ - 1.0 , 0.0 , 0.0 ,
363+
364+ - 100.0 , 0.0 , 0.0 ,
365+ 0.0 , 200.0 ,
366+ 1.0 ,
367+ 0.0 , 0.0 , 0.0
368+ ],
369+ 'pos_y' : [
370+ # Camera along +Y => +Y out of screen
371+ 1.0 , 0.0 , 0.0 ,
372+ 0.0 , 0.0 , - 1.0 ,
373+ 0.0 , 1.0 , 0.0 ,
374+
375+ 0.0 , 100.0 , 0.0 ,
376+ 0.0 , 200.0 ,
377+ 1.0 ,
378+ 0.0 , 0.0 , 0.0
379+ ],
380+ 'neg_y' : [
381+ 1.0 , 0.0 , 0.0 ,
382+ 0.0 , 0.0 , 1.0 ,
383+ 0.0 , - 1.0 , 0.0 ,
384+
385+ 0.0 , - 100.0 , 0.0 ,
386+ 0.0 , 200.0 ,
387+ 1.0 ,
388+ 0.0 , 0.0 , 0.0
389+ ],
390+ 'pos_z' : [
391+ # Camera along +Z => +Z out of screen
392+ 1.0 , 0.0 , 0.0 ,
393+ 0.0 , 1.0 , 0.0 ,
394+ 0.0 , 0.0 , 1.0 ,
395+
396+ 0.0 , 0.0 , 100.0 ,
397+ 0.0 , 200.0 ,
398+ 1.0 ,
399+ 0.0 , 0.0 , 0.0
400+ ],
401+ 'neg_z' : [
402+ 1.0 , 0.0 , 0.0 ,
403+ 0.0 , 1.0 , 0.0 ,
404+ 0.0 , 0.0 , - 1.0 ,
405+
406+ 0.0 , 0.0 , - 100.0 ,
407+ 0.0 , 200.0 ,
408+ 1.0 ,
409+ 0.0 , 0.0 , 0.0
410+ ],
411+ }
412+
413+ for direction , view in directions .items ():
414+ pymol .cmd .set_view (view )
415+ pymol .cmd .zoom (selection , buffer = 0.5 )
416+
417+ filename = f"{ prefix } _{ direction } .png"
418+ pymol .cmd .png (filename , width = width , height = height , dpi = dpi , ray = ray )
419+ print (f"Saved { filename } " )
420+ return None
421+
422+ def save_6view_pdf (image_prefix = 'tmp.csubst.pymol' ,
423+ directions = None ,
424+ pdf_filename = '6view.pdf' ):
425+ """
426+ Combines the 6 saved view images into a single PDF with 2 columns and 3 rows.
427+
428+ Parameters
429+ ----------
430+ image_prefix : str
431+ Common prefix used when saving the 6 PNG images with save_six_views.
432+ directions : list of str
433+ List of the view directions in the order you want them arranged.
434+ Default is ['pos_x','neg_x','pos_y','neg_y','pos_z','neg_z'].
435+ pdf_filename : str
436+ Name of the output PDF file.
437+ """
438+ if directions is None :
439+ directions = ['pos_x' ,'neg_x' ,'pos_y' ,'neg_y' ,'pos_z' ,'neg_z' ]
440+
441+ # Create a figure with 3 rows & 2 columns
442+ fig , axes = matplotlib .pyplot .subplots (nrows = 3 , ncols = 2 , figsize = (8.3 , 11.7 )) # A4 paper size
443+
444+ for idx , direction in enumerate (directions ):
445+ row = idx // 2
446+ col = idx % 2
447+ ax = axes [row , col ]
448+
449+ # Construct filename for each view image
450+ img_file = f"{ image_prefix } _{ direction } .png"
451+
452+ if not os .path .isfile (img_file ):
453+ print (f"Warning: { img_file } not found. Skipping." )
454+ ax .axis ('off' )
455+ ax .set_title (f"{ direction } (missing)" )
456+ continue
457+
458+ # Read and show image
459+ img = matplotlib .image .imread (img_file )
460+ ax .imshow (img )
461+
462+ # Remove axes ticks
463+ ax .axis ('off' )
464+
465+ # Optionally label each subplot
466+ ax .set_title (direction )
467+
468+ matplotlib .pyplot .tight_layout ()
469+ matplotlib .pyplot .savefig (pdf_filename )
470+ matplotlib .pyplot .close (fig )
471+ print (f"Saved 6-view PDF as { pdf_filename } " )
472+ return None
0 commit comments