# IPySlides
[](https://doi.org/10.5281/zenodo.15482350)
[](https://mybinder.org/v2/gh/massgh/ipyslides/HEAD?labpath=demo.ipynb)
[](https://asaboor-gh.github.io/einteract-docs/lab/index.html?path=IPySlides.ipynb)
[](https://badge.fury.io/py/ipyslides)
[](https://pepy.tech/project/ipyslides)
<svg width="1.25em" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="butt" stroke-linejoin="round" stroke-width="7.071067811865476">
<path d="M22.5 7.5L10 20L20 30L30 20L40 30L27.5 42.5" stroke="teal"/>
<path d="M7.5 27.5L22.5 42.5" stroke="crimson"/>
<path d="M32.5 32.5L20 20L30 10L42.5 22.5" stroke="red"/>
</svg> IPySlides is a Python library for creating interactive presentations in Jupyter notebooks. It combines the power of Markdown, LaTeX, interactive widgets, and live variable updates in a single presentation framework.
---
<p float="left">
<img src="slide.png" width="240" />
<img src="animate.gif" width="300" />
</p>
---
## Features
- đ Support for plots, widgets, and rich media
- đ¨ Customizable themes and layouts
- đą Responsive design for various screen sizes
- đ¤ Export to HTML/PDF (limited content type)
- đ¯ Frame-by-frame animations
- đ Speaker notes support
- đ Markdown, citations and settings files synchronization
- âī¸ Drawing support during presentations
---
## Quick Start
1. **Install:**
```bash
pip install ipyslides # Basic installation
pip install ipyslides[extra] # Full features
```
2. **Create Slides:**
```python
import ipyslides as isd
slides = isd.Slides()
# Add content programmatically
slides.build(-1, """
# My First Slide
- Point 1
- Point 2
$E = mc^2$
""")
# Or use cell magic
%%slide 0
# Title Slide
Welcome to IPySlides!
```
3. **Run Examples:**
```python
slides.docs() # View documentation
slides.demo() # See demo presentation
```
**⨠Try it in your browser â¨**
| Jupyterlite | Binder |
|--------------|--------|
|[](https://asaboor-gh.github.io/einteract-docs/lab/index.html?path=IPySlides.ipynb) | [](https://mybinder.org/v2/gh/massgh/ipyslides/HEAD?labpath=demo.ipynb) |
---
## Content Types
Support for various content types including:
- đ Extended Markdown, see `slides.xmd_syntax`
- đ Plots (Matplotlib, Plotly, Altair)
- đ§ Interactive Widgets
- đˇ Images and Media
- â LaTeX Equations
- ÂŠī¸ Citations and References
- đģ Auto update variables in markdown
- đĨ Videos (YouTube, local)
- đŽ Enhanced interactive widgets (with fullscreen support, thanks to `anywidget`)
```python
import numpy as np
from ipywidgets import HTML
@slides.ei.interact(html = HTML(), amplitude= (0, 2),frequency=(0, 5))
def plot(html, amplitude, frequency):
x = np.linspace(0, 2*np.pi, 100)
y = amplitude * np.sin(frequency * x)
plt.plot(x, y)
html.value = slides.plt2html(). value
```
- For comprehensive dashbords, subclass `InteractBase`
```python
import numpy as np
from ipywidgets import HTML
from ipyslides.interaction import InteractBase, callback
class MyDashboard(InteractBase):
def _interactive_params(self): # Define interactive parameters
return {
'html': HTML(),
'amplitude': (0, 2),
'frequency': (0, 5),
}
@callback
def plot(self, html, amplitude, frequency):
x = np.linspace(0, 2*np.pi, 100)
y = amplitude * np.sin(frequency * x)
plt.plot(x, y)
html.value = slides.plt2html().value
@callback('out-text')
def text(self, amplitude, frequency):
print(f"Amplitude: {amplitude}\n Frequency: {frequency}")
dash = MyDashboard(auto_update=False)
dash.relayout( # can be set via app_layout parameter
left_sidebar = dash.groups.controls,
center = ['html','out-text'], # out-plot, out-text collected in center
pane_widths = [3,5,0]
)
dash.set_css(
main = { # can be set via grid_css parameter
'grid-gap': '4px', 'margin': '8px',
'.left-sidebar': {'background': '#eee','border-radius': '8px'},
},
center = { # can be set via grid_css parameter targetting '> .center'
'> *': {'background-color': 'whitesmoke', 'border-radius': '8px','padding':'8px'}
'grid-template-columns': '5fr 3fr', # side-by-side layout for outputs
'grid-gap': '4px', # central grid gap
'> *': {'background-color': 'whitesmoke', 'border-radius': '8px','padding':'8px'}
})
display(dash)
```

See more examples in [einteract repository](https://github.com/asaboor-gh/einteract) and on [](https://mybinder.org/v2/gh/asaboor-gh/einteract/HEAD?urlpath=%2Fdoc%2Ftree%2Feinteract-demo.ipynb).
- And much more!
---
## Export Options
- **HTML Export**<br/>
Use `slides.export_html` to build static slides that you can print as well. Read export details in settings panel, where you can also export with a single click.
- **PDF Export**
1. Export to HTML first
2. Open in Chrome/Edge browser
3. Use Print â Save as PDF and enable background graphics
Navigate to [Documentation](https://asaboor-gh.github.io/ipyslides/) to see HTML slides which you can print to PDF.
---
## Advanced Features
- **Custom Objects Serialization:**
- You can serialize custom objects to HTML using `Slides.serializer` API.
- You can extend markdown syntax using `Slides.extender` API. See some good extensions to add from [PyMdown](https://facelessuser.github.io/pymdown-extensions/).
- **Speaker Notes:**
Enable via Settings Panel â Show Notes
and add notes via `slides.notes`.
- **Custom Styling:**
```python
slides.set_css({ # on all slides or slide[index,].set_css() per slide
'--bg1-color': '#f0f0f0',
'--text-color': '#333'
})
```
- **File Sync:**
Live edit a linked markdown file that updates slides in real-time using `slides.sync_with_file`.
---
## Caveats
1. **Markdown Cells:**
- Jupyter markdown cells are not processed by IPySlides
- Instead, you can use `%%slide number -m` cell magic and link an external markdown file using `slides.sync_with_file`
2. **Slide Numbering:**
- Use `-1` for automatic slide numbering
- Manual numbering requires careful tracking to avoid overwriting slides
3. **Speaker Notes:**
- Experimental feature - use with caution
---
## Development
```bash
git clone https://github.com/asaboor-gh/ipyslides.git
cd ipyslides
pip install -e .
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
---
## Documentation
- [Github Pages Documentation](https://asaboor-gh.github.io/ipyslides/)
- Full documentation: `slides.docs()` same as on github pages.
- Examples: `slides.demo()`
- [GitHub Repository](https://github.com/asaboor-gh/ipyslides)
## Acknowledgements
- [ipywidgets](https://github.com/jupyter-widgets/ipywidgets) & [anywidget](https://github.com/manzt/anywidget)
- [IPython](https://github.com/ipython/ipython)
- [Python-Markdown](https://python-markdown.github.io/)
---
Made with â¤ī¸ by Abdul Saboor
Raw data
{
"_id": null,
"home_page": "https://github.com/asaboor-gh/ipyslides",
"name": "ipyslides",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "Jupyter, Widgets, IPython",
"author": "Abdul Saboor",
"author_email": "asaboor.my@outlook.com",
"download_url": "https://files.pythonhosted.org/packages/20/c9/9bf7893112aefa7400fda7eb0ce084a42e4c8c8a6c3a381c700bf7fbd506/ipyslides-5.8.1.tar.gz",
"platform": null,
"description": "\r\n# IPySlides\r\n\r\n[](https://doi.org/10.5281/zenodo.15482350)\r\n[](https://mybinder.org/v2/gh/massgh/ipyslides/HEAD?labpath=demo.ipynb)\r\n[](https://asaboor-gh.github.io/einteract-docs/lab/index.html?path=IPySlides.ipynb)\r\n[](https://badge.fury.io/py/ipyslides)\r\n[](https://pepy.tech/project/ipyslides)\r\n\r\n<svg width=\"1.25em\" viewBox=\"0 0 50 50\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"butt\" stroke-linejoin=\"round\" stroke-width=\"7.071067811865476\">\r\n <path d=\"M22.5 7.5L10 20L20 30L30 20L40 30L27.5 42.5\" stroke=\"teal\"/>\r\n <path d=\"M7.5 27.5L22.5 42.5\" stroke=\"crimson\"/>\r\n <path d=\"M32.5 32.5L20 20L30 10L42.5 22.5\" stroke=\"red\"/>\r\n</svg> IPySlides is a Python library for creating interactive presentations in Jupyter notebooks. It combines the power of Markdown, LaTeX, interactive widgets, and live variable updates in a single presentation framework.\r\n\r\n---\r\n\r\n<p float=\"left\"> \r\n <img src=\"slide.png\" width=\"240\" />\r\n <img src=\"animate.gif\" width=\"300\" />\r\n</p>\r\n\r\n---\r\n\r\n## Features\r\n\r\n- \ud83d\udcca Support for plots, widgets, and rich media\r\n- \ud83c\udfa8 Customizable themes and layouts\r\n- \ud83d\udcf1 Responsive design for various screen sizes\r\n- \ud83d\udce4 Export to HTML/PDF (limited content type)\r\n- \ud83c\udfaf Frame-by-frame animations\r\n- \ud83d\udcdd Speaker notes support\r\n- \ud83d\udd04 Markdown, citations and settings files synchronization\r\n- \u270f\ufe0f Drawing support during presentations\r\n\r\n--- \r\n\r\n## Quick Start\r\n\r\n1. **Install:**\r\n```bash\r\npip install ipyslides # Basic installation\r\npip install ipyslides[extra] # Full features\r\n```\r\n\r\n2. **Create Slides:**\r\n```python\r\nimport ipyslides as isd\r\nslides = isd.Slides()\r\n\r\n# Add content programmatically\r\nslides.build(-1, \"\"\"\r\n# My First Slide\r\n- Point 1\r\n- Point 2\r\n$E = mc^2$\r\n\"\"\")\r\n\r\n# Or use cell magic\r\n%%slide 0\r\n# Title Slide\r\nWelcome to IPySlides!\r\n```\r\n\r\n3. **Run Examples:**\r\n```python\r\nslides.docs() # View documentation\r\nslides.demo() # See demo presentation\r\n```\r\n\r\n**\u2728 Try it in your browser \u2728**\r\n| Jupyterlite | Binder |\r\n|--------------|--------|\r\n|[](https://asaboor-gh.github.io/einteract-docs/lab/index.html?path=IPySlides.ipynb) | [](https://mybinder.org/v2/gh/massgh/ipyslides/HEAD?labpath=demo.ipynb) |\r\n\r\n---\r\n\r\n## Content Types\r\n\r\nSupport for various content types including:\r\n\r\n- \ud83d\udcdc Extended Markdown, see `slides.xmd_syntax`\r\n- \ud83d\udcca Plots (Matplotlib, Plotly, Altair)\r\n- \ud83d\udd27 Interactive Widgets\r\n- \ud83d\udcf7 Images and Media\r\n- \u2797 LaTeX Equations\r\n- \u00a9\ufe0f Citations and References\r\n- \ud83d\udcbb Auto update variables in markdown\r\n- \ud83c\udfa5 Videos (YouTube, local)\r\n- \ud83c\udfae Enhanced interactive widgets (with fullscreen support, thanks to `anywidget`)\r\n\r\n```python\r\nimport numpy as np\r\nfrom ipywidgets import HTML\r\n\r\n@slides.ei.interact(html = HTML(), amplitude= (0, 2),frequency=(0, 5))\r\ndef plot(html, amplitude, frequency):\r\n x = np.linspace(0, 2*np.pi, 100)\r\n y = amplitude * np.sin(frequency * x)\r\n plt.plot(x, y)\r\n html.value = slides.plt2html(). value\r\n```\r\n\r\n- For comprehensive dashbords, subclass `InteractBase`\r\n\r\n```python\r\nimport numpy as np\r\nfrom ipywidgets import HTML\r\nfrom ipyslides.interaction import InteractBase, callback \r\n\r\nclass MyDashboard(InteractBase):\r\n def _interactive_params(self): # Define interactive parameters\r\n return {\r\n 'html': HTML(),\r\n 'amplitude': (0, 2),\r\n 'frequency': (0, 5),\r\n }\r\n\r\n @callback\r\n def plot(self, html, amplitude, frequency):\r\n x = np.linspace(0, 2*np.pi, 100)\r\n y = amplitude * np.sin(frequency * x)\r\n plt.plot(x, y)\r\n html.value = slides.plt2html().value\r\n \r\n @callback('out-text')\r\n def text(self, amplitude, frequency):\r\n print(f\"Amplitude: {amplitude}\\n Frequency: {frequency}\")\r\n\r\ndash = MyDashboard(auto_update=False)\r\ndash.relayout( # can be set via app_layout parameter\r\n left_sidebar = dash.groups.controls, \r\n center = ['html','out-text'], # out-plot, out-text collected in center\r\n pane_widths = [3,5,0]\r\n)\r\ndash.set_css(\r\n main = { # can be set via grid_css parameter\r\n 'grid-gap': '4px', 'margin': '8px',\r\n '.left-sidebar': {'background': '#eee','border-radius': '8px'},\r\n },\r\n center = { # can be set via grid_css parameter targetting '> .center'\r\n '> *': {'background-color': 'whitesmoke', 'border-radius': '8px','padding':'8px'}\r\n 'grid-template-columns': '5fr 3fr', # side-by-side layout for outputs\r\n 'grid-gap': '4px', # central grid gap\r\n '> *': {'background-color': 'whitesmoke', 'border-radius': '8px','padding':'8px'}\r\n})\r\ndisplay(dash)\r\n```\r\n\r\nSee more examples in [einteract repository](https://github.com/asaboor-gh/einteract) and on [](https://mybinder.org/v2/gh/asaboor-gh/einteract/HEAD?urlpath=%2Fdoc%2Ftree%2Feinteract-demo.ipynb).\r\n\r\n- And much more!\r\n\r\n---\r\n\r\n## Export Options\r\n\r\n- **HTML Export**<br/>\r\nUse `slides.export_html` to build static slides that you can print as well. Read export details in settings panel, where you can also export with a single click.\r\n\r\n- **PDF Export**\r\n1. Export to HTML first\r\n2. Open in Chrome/Edge browser\r\n3. Use Print \u2192 Save as PDF and enable background graphics\r\n\r\nNavigate to [Documentation](https://asaboor-gh.github.io/ipyslides/) to see HTML slides which you can print to PDF.\r\n\r\n---\r\n\r\n## Advanced Features\r\n- **Custom Objects Serialization:**\r\n - You can serialize custom objects to HTML using `Slides.serializer` API.\r\n - You can extend markdown syntax using `Slides.extender` API. See some good extensions to add from [PyMdown](https://facelessuser.github.io/pymdown-extensions/).\r\n\r\n- **Speaker Notes:**\r\n Enable via Settings Panel \u2192 Show Notes\r\n and add notes via `slides.notes`.\r\n\r\n- **Custom Styling:**\r\n```python\r\nslides.set_css({ # on all slides or slide[index,].set_css() per slide\r\n '--bg1-color': '#f0f0f0',\r\n '--text-color': '#333'\r\n})\r\n```\r\n\r\n- **File Sync:**\r\n Live edit a linked markdown file that updates slides in real-time using `slides.sync_with_file`.\r\n\r\n---\r\n\r\n## Caveats\r\n\r\n1. **Markdown Cells:** \r\n - Jupyter markdown cells are not processed by IPySlides\r\n - Instead, you can use `%%slide number -m` cell magic and link an external markdown file using `slides.sync_with_file`\r\n\r\n2. **Slide Numbering:**\r\n - Use `-1` for automatic slide numbering\r\n - Manual numbering requires careful tracking to avoid overwriting slides\r\n\r\n3. **Speaker Notes:**\r\n - Experimental feature - use with caution\r\n\r\n---\r\n\r\n## Development\r\n\r\n```bash\r\ngit clone https://github.com/asaboor-gh/ipyslides.git\r\ncd ipyslides\r\npip install -e .\r\n```\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please feel free to submit a Pull Request.\r\n\r\n---\r\n\r\n## Documentation\r\n\r\n- [Github Pages Documentation](https://asaboor-gh.github.io/ipyslides/)\r\n- Full documentation: `slides.docs()` same as on github pages.\r\n- Examples: `slides.demo()`\r\n- [GitHub Repository](https://github.com/asaboor-gh/ipyslides)\r\n\r\n\r\n## Acknowledgements\r\n\r\n- [ipywidgets](https://github.com/jupyter-widgets/ipywidgets) & [anywidget](https://github.com/manzt/anywidget)\r\n- [IPython](https://github.com/ipython/ipython)\r\n- [Python-Markdown](https://python-markdown.github.io/)\r\n\r\n---\r\n\r\nMade with \u2764\ufe0f by Abdul Saboor\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Live rich content slides in jupyter notebook",
"version": "5.8.1",
"project_urls": {
"Bug Tracker": "https://github.com/asaboor-gh/ipyslides/issues",
"Homepage": "https://github.com/asaboor-gh/ipyslides"
},
"split_keywords": [
"jupyter",
" widgets",
" ipython"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f909ea56b06843bff0aac4b6afe12ddb2484ba037f18929e03dde54e5f7f4c53",
"md5": "0ac77e51d9fe8ea3f35aadb6b6158d7e",
"sha256": "e546d7764745f06e178d440d4b4790d632d7f425230d90524f5c29ced8493e5b"
},
"downloads": -1,
"filename": "ipyslides-5.8.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "0ac77e51d9fe8ea3f35aadb6b6158d7e",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.8",
"size": 172079,
"upload_time": "2025-07-11T05:27:03",
"upload_time_iso_8601": "2025-07-11T05:27:03.664324Z",
"url": "https://files.pythonhosted.org/packages/f9/09/ea56b06843bff0aac4b6afe12ddb2484ba037f18929e03dde54e5f7f4c53/ipyslides-5.8.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "20c99bf7893112aefa7400fda7eb0ce084a42e4c8c8a6c3a381c700bf7fbd506",
"md5": "7f7dbc90c6c20bf1c75259ba01f347c3",
"sha256": "b3a48dcc2e47c314b6d6acc2d887e564aa949eca26ca3fb11f3a6dbf15ef24e5"
},
"downloads": -1,
"filename": "ipyslides-5.8.1.tar.gz",
"has_sig": false,
"md5_digest": "7f7dbc90c6c20bf1c75259ba01f347c3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 156658,
"upload_time": "2025-07-11T05:27:05",
"upload_time_iso_8601": "2025-07-11T05:27:05.443593Z",
"url": "https://files.pythonhosted.org/packages/20/c9/9bf7893112aefa7400fda7eb0ce084a42e4c8c8a6c3a381c700bf7fbd506/ipyslides-5.8.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-11 05:27:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "asaboor-gh",
"github_project": "ipyslides",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "anywidget",
"specs": [
[
"==",
"0.9.13"
]
]
},
{
"name": "tldraw",
"specs": [
[
"==",
"2.2.4"
]
]
},
{
"name": "ipython",
"specs": [
[
">=",
"8.7"
]
]
},
{
"name": "jupyterlab",
"specs": [
[
">=",
"3.5.2"
]
]
},
{
"name": "markdown",
"specs": []
},
{
"name": "altair",
"specs": []
},
{
"name": "ipywidgets",
"specs": [
[
">=",
"8.0.4"
]
]
},
{
"name": "numpy",
"specs": []
},
{
"name": "pandas",
"specs": []
},
{
"name": "matplotlib",
"specs": []
},
{
"name": "voila",
"specs": [
[
">=",
"0.4.0"
]
]
},
{
"name": "markdown-customblocks",
"specs": []
},
{
"name": "pillow",
"specs": [
[
">=",
"9.3.0"
]
]
},
{
"name": "plotly",
"specs": [
[
"==",
"6.0.1"
]
]
}
],
"lcname": "ipyslides"
}