Skip to main content

Chemistry visualization in Jupyter Notebooks with the OpenEye Toolkits

Project description

CNotebook

Python 3.11+ OpenEye Toolkits

Author: Scott Arne Johnson (scott.arne.johnson@gmail.com)

Documentation: https://cnotebook.readthedocs.io/en/latest/

CNotebook provides chemistry visualization for Jupyter Notebooks and Marimo using the OpenEye Toolkits. Import the package and your molecular data will automatically render as chemical structures without additional configuration.

Supports both Pandas and Polars DataFrames with automatic environment detection.

Render molecules in Jupyter and Marimo with style

Maintain Jupyter table formatting for Pandas and Polars

Compatible with native Marimo tables

Interactive molecule grids that support data

Table of Contents

Installation

pip install cnotebook

Prerequisites:

  • OpenEye Toolkits: pip install openeye-toolkits
  • You must have a valid license (free for academia).

Optional backends:

  • Pandas support: pip install pandas oepandas
  • Polars support: pip install polars oepolars

Both backends can be installed together, neither are required unless you want to work with DataFrames.

Getting Started

The fastest way to learn CNotebook is through the example notebooks in the examples/ directory:

Environment Pandas Polars MolGrid
Jupyter pandas_jupyter_demo.ipynb polars_jupyter_demo.ipynb molgrid_jupyter_demo.ipynb
Marimo pandas_marimo_demo.py polars_marimo_demo.py molgrid_marimo_demo.py

Basic Usage

import cnotebook
from openeye import oechem

# Create a molecule (supports titles in SMILES)
mol = oechem.OEGraphMol()
oechem.OESmilesToMol(mol, "c1cnccc1 Benzene")

# Display it - automatically renders as a chemical structure
mol

CNotebook registers formatters so OpenEye molecule objects display as chemical structures instead of text representations.

Features

Automatic Rendering

  • Zero configuration required
  • Supports Jupyter Notebooks and Marimo
  • Automatic environment and backend detection

Molecule Support

  • Direct rendering of oechem.OEMolBase objects
  • Advanced rendering with OE2DMolDisplay options
  • Pandas integration via OEPandas
  • Polars integration via OEPolars

Visualization Options

  • PNG (default) or SVG output
  • Configurable width, height, and scaling
  • Substructure highlighting with SMARTS patterns
  • Molecular alignment to reference structures

MolGrid Interactive Visualization

  • Paginated grid display for browsing molecules
  • Text search across molecular properties
  • SMARTS substructure filtering
  • Selection tools with export to SMILES or CSV
  • Information tooltips with molecular data
  • DataFrame integration with automatic field detection

DataFrame Integration

  • Automatic molecule column detection and rendering
  • Per-row substructure highlighting
  • Molecular alignment within DataFrames
  • Fingerprint similarity visualization
  • Property calculations on molecule columns

MolGrid Interactive Visualization

MolGrid provides an interactive grid for browsing molecular datasets with search and selection capabilities.

Basic Example

from cnotebook import MolGrid
from openeye import oechem

# Create molecules
molecules = []
for smi in ["CCO", "c1ccccc1", "CC(=O)O"]:
    mol = oechem.OEGraphMol()
    oechem.OESmilesToMol(mol, smi)
    molecules.append(mol)

# Display interactive grid
grid = MolGrid(molecules)
grid.display()

Search and Filter

MolGrid provides two search modes:

  • Properties mode: Search by molecular titles and configurable text fields
  • SMARTS mode: Filter by substructure patterns with match highlighting

Selection

  • Click molecules or checkboxes to select
  • Use the menu for Select All, Clear, and Invert operations
  • Export selections to SMILES or CSV files

Information Tooltips

  • Hover over the information button to view molecular data
  • Click to pin tooltips for comparing multiple molecules
  • Configure displayed fields with the data parameter

DataFrame Integration

import pandas as pd
from cnotebook import MolGrid
from openeye import oechem, oemolprop

# Create DataFrame
df = pd.DataFrame(
    {"Molecule": ["CCO", "c1ccccc1", "CC(=O)O"]}
).chem.as_molecule("Molecule")

# Calculate some properties
df["MW"] = df.Molecule.apply(oechem.OECalculateMolecularWeight)
df["PSA"] = df.Molecule.apply(oemolprop.OEGet2dPSA)
df["HBA"] = df.Molecule.apply(oemolprop.OEGetHBondAcceptorCount)
df["HBD"] = df.Molecule.apply(oemolprop.OEGetHBondDonorCount)

# Display the grid (using the 'Molecule' column for structures)
grid = df.chem.molgrid("Molecule")
grid.display()

This will display the same grid as above, but with molecule data if you click the "i".

Retrieving Selections

# Get selected molecules
selected_mols = grid.get_selection()

# Get selected indices
indices = grid.get_selection_indices()

DataFrame Integration

Pandas DataFrames

import cnotebook
import oepandas as oepd

# Read the example unaligned molecules
df = oepd.read_sdf("examples/assets/rotations.sdf", no_title=True)

# Rename the "Molecule" column to "Original" so that we can
# see the original unaligned molecules
df = df.rename(columns={"Molecule": "Original"})

# Create a new molecule column called "Aligned" so that we can
# see the aligned molecules
df["Aligned"] = df.Original.chem.copy_molecules()

# Add substructure highlighting
df["Original"].chem.highlight("c1ccccc1")
df["Aligned"].chem.highlight("c1ccccc1")

# Align molecules to a reference
df["Aligned"].chem.align_depictions("first")

# Display the DataFrame
df

Polars DataFrames

Same example as above using Polars instead of Pandas. The main difference is that some methods are called from the DataFrame instead of the Series.

import cnotebook
import oepolars as oepl

# Read the example unaligned molecules
df = oepl.read_sdf("examples/assets/rotations.sdf", no_title=True)

# Rename the "Molecule" column to "Original" so that we can
# see the original unaligned molecules
df = df.rename({"Molecule": "Original"})

# # Create a new molecule column called "Aligned" so that we can
# # see the aligned molecules
df = df.chem.copy_molecules("Original", "Aligned")

# # Add substructure highlighting
df.chem.highlight("Original", "c1ccccc1")
df.chem.highlight("Aligned", "c1ccccc1")

# # Align molecules to a reference
df["Aligned"].chem.align_depictions("first")

# Display the DataFrame
df

This will display the exact same table as above.

Example Notebooks

The examples/ directory contains comprehensive tutorials for learning CNotebook:

Jupyter Notebooks

Marimo Applications

Recommended starting point: Begin with the MolGrid demo for your preferred environment, then explore the Pandas or Polars tutorials for DataFrame integration.

Contributing

Contributions are welcome. Please ensure your code:

  • Follows existing code style and conventions
  • Includes appropriate tests
  • Works with both Jupyter and Marimo environments
  • Maintains compatibility with OpenEye Toolkits
  • Works with both Pandas and Polars when applicable

See CONTRIBUTING.md for detailed guidelines.

License

This project is licensed under the MIT License. See LICENSE for details.

Support

For bug reports, feature requests, or questions, please open an issue on GitHub or contact scott.arne.johnson@gmail.com.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cnotebook-2.1.2-py3-none-any.whl (65.9 kB view details)

Uploaded Python 3

File details

Details for the file cnotebook-2.1.2-py3-none-any.whl.

File metadata

  • Download URL: cnotebook-2.1.2-py3-none-any.whl
  • Upload date:
  • Size: 65.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for cnotebook-2.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0b3afd3f49932615534bfb304895b3615eec9d756c60fbe59dabff6b29bc5ca0
MD5 d6a64b4e1f6932b18d9f09a2d0bed158
BLAKE2b-256 6c8591f2ccd3411a7f91219a02dc55821de3e3a3c990995e22a594337cd121ca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page