# CanvasXpress for Python
<a href="https://www.canvasxpress.org">
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/images/hexagon.png" align="left" width="175" style="vertical-align:middle;margin:10px 10px">
</a>
<br>
[***CanvasXpress***](https://www.canvasxpress.org) was developed as the core visualization component for bioinformatics
and systems biology analysis at Bristol-Myers Squibb. It supports a large number
of [visualizations ](https://www.canvasxpress.org/examples.html)
to display scientific and non-scientific data. ***CanvasXpress*** also includes a simple and unobtrusive
[user interface](https://www.canvasxpress.org/docs/interface.html) to explore complex data sets, a sophisticated and
unique mechanism to keep track of all user customization for
[Reproducible Research ](https://www.canvasxpress.org/docs/audit.html) purposes, as well as an 'out of the box'
broadcasting capability to synchronize selected data points across all ***CanvasXpress*** plots in a page. Data can be
easily sorted, grouped, transposed, transformed or clustered dynamically. The fully customizable mouse events as well as
the zooming, panning and drag-and-drop capabilities are features that make this library unique in its class.
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/images/sample_graphs.png" align="center" width="726"></a>
***CanvasXpress*** can be used for native Python integration for the following environments:
- [Shiny for Python](https://shiny.posit.co/py/)
- [Streamlit](https://streamlit.io/)
- [Plotly Dash](https://dash.plotly.com/)
- [Jupyter](https://jupyter.org/)
- [Flask](https://flask.palletsprojects.com/en/1.1.x/)
- [Django](https://www.djangoproject.com/)
The RStudio IDE Viewer is also used when running code chunks in Jupyter, Quarto, and RMD Python code chunks.
This ***CanvasXpress*** Python package is maintained by [Dr. Todd C. Brett](https://github.com/docinfosci), with support
from [Aggregate Genius Inc.](https://www.aggregate-genius.com), in cooperation with Dr. Isaac Neuhaus and the
***CanvasXpress*** team.
## Project Status
[![Release](https://img.shields.io/pypi/v/canvasxpress.svg)](https://pypi.org/project/canvasxpress)
[![Compatibility](https://img.shields.io/pypi/pyversions/canvasxpress.svg)](https://pypi.org/project/canvasxpress)
[![Implementations](https://img.shields.io/pypi/implementation/canvasxpress.svg)](https://pypi.org/project/canvasxpress)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/canvasxpress)](https://pypi.org/project/canvasxpress)
[![docinfosci](https://circleci.com/gh/docinfosci/canvasxpress-python/tree/main.svg?style=shield)](https://circleci.com/gh/docinfosci/canvasxpress-python/?branch=main)
[![Coverage Status](https://coveralls.io/repos/github/docinfosci/canvasxpress-python/badge.svg?branch=main)](https://coveralls.io/github/docinfosci/canvasxpress-python?branch=main)
[![Activity](https://img.shields.io/github/last-commit/docinfosci/canvasxpress-python/develop)](https://github.com/docinfosci/canvasxpress-python)
## Documentation, Installation, and Usage
### Documentation
Documentation is maintained at [CanvasXpress.org](https://www.canvasxpress.org) and LinkedIn:
- [Introduction to CanvasXpress for Python](https://www.linkedin.com/pulse/introducing-canvasxpress-python-todd-brett-hew0f/?trackingId=G8kTE2QyRH%2BrcVSzxJc8Hg%3D%3D)
### Installation
CanvasXpress for Python can be installed using _pip_:
The essential CanvasXpress package, for use with the CLI or flask and similar environments, can be installed using:
```terminal
pip install canvasxpress
```
or
```terminal
pip install "canvasxpress[core]"
```
In addition to _core_, the following additional targets can be used:
- _jupyter_ - installs additional packages to support rendering in Jupyter, Quarto, and IPython documents
- _dash_ - installs additional packages to support rendering in Plotly Dash applications
- _streamlit_ - installs additional packages to support rendering in Snowflake Streamlit applications
- _shiny_ - installs additional packages to support rendering in Posit Shiny for Python applications
- _rstudio_ - installs additional packages to support rendering in the Posit RStudio IDE Viewer, plus includes the same packages for jupyter and shiny
- _all_ - installs all additional packages to support rendering in any supported document or application
### Drawing Charts
The `CanvasXpress` object defines what a chart should contain and how it should be formatted, but rendering the chart
is performed by the functions `graph()` and `show_in_browser()`.
To use `graph()` import it from `canvasxpress.plot` and then call it by passing a `CanvasXpress` object. For example, a
Quarto, RMD, or Jupyter Notebook code chunk could be:
```python
from random import random
from canvasxpress.canvas import CanvasXpress
from canvasxpress.plot import graph
graph(
CanvasXpress(
data={
"y": {
"data": [
[random() % 100 for i in range(20)]
],
"vars": ["A"],
}
},
config={
"background": "rgb(255,255,255)",
"colorScheme": "CanvasXpress",
"graphOrientation": "vertical",
"graphType": "Area",
"objectBorderColor": False,
"plotBox": False,
"plotBoxColor": "rgb(204,204,204)",
"showLegend": False,
"showLegendBorder": True,
"smpLabelRotate": 90,
"smpTitle": "time",
"xAxis": ["A"],
"xAxisTickRightShow": False,
"yAxisTickTopShow": False
},
width=609,
height=609
)
)
```
Some application frameworks, such as _Shiny for Python_ and _Plotly Dash_, expect an object to be rendered to the
framework as part of the reactive flow. In these contexts, the `graph()` function creates an appropriate object
and returns it. That value can be assigned to a variable to be returned at a later point in the code, or be
immediately returned. See the Shiny for Python and Dash examples for specific usage.
`show_in_browser()` is similar to `graph()` except that it opens a browser window on the local system and displays the
chart. It's used to facilitate learning and debugging.
`graph()` does a good job of determining the runtime context to choose how the chart should be rendered, but in the
case installed packages or runtime configurations confuse the function an environment variable can be set to override
how `graph()` performs the rendering. Set `CANVASXPRESS_TARGET_CONTEXT` to be one of these values as appropriate for
this situation (and don't forget to pip install the necessary package support):
- rstudio
- shiny
- jupyter
- dash
- streamlit
- browser
For example:
```python
from os import environ
environ["CANVASXPRESS_TARGET_CONTEXT"] = "jupyter"
```
or via a shell (_bash_ example provided):
```shell
export CANVASXPRESS_TARGET_CONTEXT="jupyter"
```
### Default and Pinned CanvasXpress JavaScript Editions
CanvasXpress for Python generates JavaScript that assumes use of the latest available edition of CanvasXpress for
JavaScript, but it can be set to use a specific edition.
Review this site for available versions:
https://cdnjs.com/libraries/canvasXpress
The desired version is expressed as a `str`. Prior to generating a CanvasXpress chart use the following code to set
the edition that shall be used:
```python
from canvasxpress.canvas import CanvasXpress
CanvasXpress.set_cdn_edition("48.3") # Or whatever available version is desired.
```
To use the default edition once again during the runtime session set the value to `None`.
This is the best way to assure a specific chart behavior for production application releases; however, once set any
new JavaScript edition features or fixes will not be available until the code is removed or a different version is set.
### Customizing Charts
Generally speaking, a `CanvasXpress` object accepts the following parameters:
#### render_to
`render_to` is a `str` value that identifies the chart when rendered into HTML. JavaScript functions can use this ID
to access the chart and perform CanvasXpress operations within the browser. Omitting `render_to` or setting it to
`None` will make the `CanvasXpress` object assume an anonymous mode in which a new GUID will be generated each time
`graph()` is called. If the chart will not be maniluated using JavaScript in the browser it is fine for charts to be anonymous.
__NOTE:__ React environments regularly destroy and rebuild objects as the page is updated. In these environments it is
possible for the timing of object destruction and JavaScript execution to cause a crash. The best defense is to either
use anonymous mode, or if an ID must be known then a unique identifier should be set each time `graph()` is called. In
this manner an ID for a chart in the middle of being recreated is never referenced. For example:
```python
chart = CanvasXpress(...)
chart.render_to = str(guid4()).replace("-", "_")
return graph(chart)
```
Plotly's Dash framework uses React, and Dash applications should consider using only anonymous charts or assigning
unique values as the ID similar to the above code. Shiny for Python does not seem to suffer from this challenge.
#### data
`data` sets the chart's data and metadata. This is an involved topic, and the [introductory article](https://www.linkedin.com/pulse/introducing-canvasxpress-python-todd-brett-hew0f/?trackingId=G8kTE2QyRH%2BrcVSzxJc8Hg%3D%3D)
is an excellent read to understand how data should be shaped. In general, data will be a `dict`, Web URL, or `str`.
Data dict example:
```python
data_for_use_in_chart = {
"y": {
"data": [
[random() % 100 for i in range(20)]
],
"vars": ["A"],
}
}
```
Data URL example:
```python
data_for_use_in_chart = "https://corgis-edu.github.io/corgis/datasets/csv/state_demographics/state_demographics.csv"
```
Data text (CSV) example:
```python
data_for_use_in_chart = """
"State","Population.Population Percent Change","Population.2014 Population"
"Connecticut","-10.2","3605944"
"Delaware","8.4","989948"
"""
```
#### config
`config` describes the chart's formatting. It is a `dict` in which properties are specified and assigned values. All
of the values must be compliant with Python's `json.dumps()` function. For example:
```python
config={
"background": "rgb(255,255,255)",
"colorScheme": "CanvasXpress",
"graphOrientation": "vertical",
"graphType": "Area",
"objectBorderColor": False,
"plotBox": False,
"plotBoxColor": "rgb(204,204,204)",
"showLegend": False,
"showLegendBorder": True,
"smpLabelRotate": 90,
"smpTitle": "time",
"xAxis": ["A"],
"xAxisTickRightShow": False,
"yAxisTickTopShow": False
},
```
#### width and height
`width` and `height` specify the chart's dimensions as pixels. If ommitted the CanvasXpress edition active for the
browser will assign default values, such as 500px by 500px.
#### Javascript Events
CanvasXpress provides support for Javascript events via hook functions that are called when events occur, such as mouse
movement or clicks. These events are supported via the canvasxpress.js sub-package. `CXEvent` objects hold the
Javascript instructions for Web events. An example event for graph clicks with popup information is:
```python
from canvasxpress.js.function import CXEvent
CXEvent(
id="click",
script="""
var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];
t.showInfoSpan(e, s);
"""
)
```
The general JavaScript template of a CanvasXpress Javascript hook function is:
```javascript
function (o, e, t) {
// script logic goes here
};
```
`CXEvent` objects can be provided as a single object or as a list. Here's an example of an event the provides
additional information about chart data upon a user click:
```python
from canvasxpress.canvas import CanvasXpress
from canvasxpress.plot import graph
from canvasxpress.js.function import CXEvent
graph(
CanvasXpress(
render_to="example_chart",
data={
"y": {
"vars": ["Gene1"],
"smps": ["Smp1", "Smp2", "Smp3"],
"data": [[10, 35, 88]]
}
},
config={
"graphOrientation": "vertical",
"graphType": "Bar",
"showLegend": False,
"smpLabelRotate": 90,
"smpTitle": "Samples",
"theme": "CanvasXpress",
"title": "Bar Graph Title",
"xAxisTitle": "Value"
},
events=[
CXEvent(
id="click",
script="""
var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];
t.showInfoSpan(e, s);
"""
),
]
)
)
```
## Converting to and from Reproducible JSON
CanvasXpress for Python can also convert to and from reproducible JSONs usable with the JavaScript and R editions of the
library. `convert_to_reproducible_json` takes an existing CanvasXpress object and provides a `str` copy of the JSON,
which can then be logged for debugging or saved to disk for use elsewhere. `convert_from_reproducible_json` does the
opposite by taking a reproducible JSON `str` and providing the CanvasXpress object equivalent.
_Note: Events are not currently supported for import. This will be provided in a future edition. Export supports events._
For example, do the following to see the JSON in the Python console:
```python
from canvasxpress.canvas import CanvasXpress
from canvasxpress.plot import convert_to_reproducible_json
from canvasxpress.js.function import CXEvent
print(
convert_to_reproducible_json(
CanvasXpress(
render_to="example_chart",
data={
"y": {
"vars": ["Gene1"],
"smps": ["Smp1", "Smp2", "Smp3"],
"data": [[10, 35, 88]]
}
},
config={
"graphOrientation": "vertical",
"graphType": "Bar",
"showLegend": False,
"smpLabelRotate": 90,
"smpTitle": "Samples",
"theme": "CanvasXpress",
"title": "Bar Graph Title",
"xAxisTitle": "Value"
},
events=[
CXEvent(
id="click",
script="""
var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];
t.showInfoSpan(e, s);
"""
),
]
)
)
)
```
The console would display:
```text
{
"renderTo": "example_chart",
"data": {"y": {"vars": ["Gene1"], "smps": ["Smp1", "Smp2", "Smp3"], "data": [[10, 35, 88]]}, "x": {}, "z": {}},
"config": {"graphOrientation": "vertical", "graphType": "Bar", "showLegend": false, "smpLabelRotate": 90, "smpTitle": "Samples", "theme": "CanvasXpress", "title": "Bar Graph Title", "xAxisTitle": "Value"},
"afterRender": [],
"otherParams": {},
"events": {'click': function(o, e, t){
var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];
t.showInfoSpan(e, s);
}},
"width": 500,
"height": 500
}
```
This text could be saved to a file, such as `example.json`, and then dragged onto a CanvasXpress chart in a browser
to load the equivalent chart. In fact, CanvasXpress for Python uses the core functionality producing JSON output to
make charts available in contexts such as Dash and Shiny.
## Application, NoteBook, and Console Examples
### Rendering Charts in the RStudio IDE Viewer Pane
The RStudio IDE's Viewer panel is now supported for rendering interactive charts in the Viewer! When the `graph()`
function is called it detects that RStudio is running and renders the chart in the Viewer instead of a document,
such as for Quarto code chunks. However, if the document is a Quarto or RMD file and the appropriate HTML (etc.)
generation is performed then the CanvasXpress charts will be embedded in the generated output file as normal.
### A Basic Python Script / Console Example
Charts can be defined in scripts or a console session and then displayed using the default browser, assuming that a
graphical browser with Javascript support is available on the host system. To do so use the `show_in_browser()`
function instead of graph()`.
```python
from canvasxpress.canvas import CanvasXpress
from canvasxpress.plot import show_in_browser
if __name__ == "__main__":
# Define a CX bar chart with some basic data
chart: CanvasXpress = CanvasXpress(
data={
"y": {
"vars": ["Gene1"],
"smps": ["Smp1", "Smp2", "Smp3"],
"data": [[10, 35, 88]]
}
},
config={
"graphType": "Bar"
}
)
# Display the chart in its own Web page
show_in_browser(chart)
```
Upon running the example the following chart will be displayed on systems such as MacOS X, Windows, and Linux with
graphical systems:
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/flask_bar_chart_basic.png" align="center" width="600"></a>
### A Shiny for Python Example
[Shiny for Python](https://shiny.posit.co/py/) is a new dashboard framework inspired by the highly successful Shiny for
R framework produced by Posit (formerly RStudio). This example shows how to create a basic Shiny for Python application
using a CanvasXpress Shiny element.
A basic Shiny for Python app provides a means by which:
1. A local development server can be started
1. A function can respond to input or draw an initial UI
First install Shiny for Python and CanvasXpress for Python:
```terminal
pip install shiny
pip install canvasxpress[shiny]
```
Then create a demo file, such as `app.py`, and insert:
```python
from random import random
from shiny import App, ui, render, reactive
from canvasxpress.canvas import CanvasXpress
from canvasxpress.render.shiny import output_canvasxpress
from canvasxpress.plot import graph
app_ui = ui.page_fluid(
ui.row(
ui.input_slider(
"points_desired",
"Points",
min=0,
max=100,
value=0,
),
),
ui.row(
output_canvasxpress("chart_view"),
)
)
def server(input, output, session):
@render.ui
@reactive.event(input.points_desired)
def chart_view():
return graph(
CanvasXpress(
data={
"y": {
"data": [
[random() % 100 for i in range(input.points_desired())]
],
"vars": ["A"],
}
},
config={
"background": "rgb(255,255,255)",
"colorScheme": "CanvasXpress",
"graphOrientation": "vertical",
"graphType": "Area",
"objectBorderColor": False,
"plotBox": False,
"plotBoxColor": "rgb(204,204,204)",
"showLegend": False,
"showLegendBorder": True,
"smpLabelRotate": 90,
"smpTitle": "time",
"xAxis": ["A"],
"xAxisTickRightShow": False,
"yAxisTickTopShow": False
},
width=500,
height=500
)
)
app = App(app_ui, server)
```
#### Run the App and View the Page
On the command line, execute:
```terminal
shiny run --reload --launch-browser app.py
```
And output similar to the following will be provided:
```terminal
Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
Browsing to `http://localhost:8000/` will result in a page with a CanvasXpress chart, which is being hosted by the Shiny
for Python framework:
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/shiny_chart_example.png" align="center" width="600"></a>
Congratulations! You have created a Shiny for Python CanvasXpress app!
### A Streamlit Example
[Streamlit](https://streamlit.io) is a popular dashboard framework that is simplified compared to Dash and Shiny, but
just as powerful in terms of reactivity and extensions. This example shows how to create a basic Streamlit application
using a CanvasXpress Streamlit element.
A basic Streamlit app provides a means by which:
1. A local development server can be started
1. A function can respond to a URL
First install Streamlit and CanvasXpress for Python:
```terminal
pip install streamlit
pip install canvasxpress[streamlit]
```
Then create a demo file, such as `app.py`, and insert:
```python
import random
import streamlit as st
from canvasxpress.canvas import CanvasXpress
from canvasxpress.plot import graph
# A basic bar chart. It's anonymous, so no render_to. Data is added during the draw phase.
chord_chart = CanvasXpress(
config={
"graphOrientation": "vertical",
"plotBox": True,
"showLegend": False,
"smpLabelRotate": 90,
"smpTitle": "Samples",
"theme": "CanvasXpress",
"title": "Bar Graph Title",
"xAxis": ["V1"],
"xAxisTitle": "Value",
"graphType": "Bar"
},
width=500,
height=500
)
# Write the UI to the browser
# This code will be re-executed with each click of the button
# Name the theme
st.title('CanvasXpress in Streamlit!')
# Some columns to organize the button and chart
column1, column2 = st.columns(2)
# A column with our data generator button
column1.write(
# This has no associated action, so by default it triggers a redraw of the UI.
st.button("Generate New Data")
)
# Another column with the chart displayed
# With each redraw generate new random values
chord_chart.data = {
"y": {
"vars": ["V1"],
"smps": ["S1", "S2", "S3"],
"data": [
[
random.randint(100, 10000),
random.randint(100, 10000),
random.randint(100, 10000),
]
]
}
}
column2.write(
# This plots the CanvasXpress chart into the UI.
graph(chord_chart)
)
```
#### Run the App and View the Page
On the command line, execute:
```terminal
streamlit run app.py
```
And output similar to the following will be provided:
```terminal
Running on http://localhost:8501/ (Press CTRL+C to quit)
```
Browsing to `http://localhost:8501/` will result in a page with a CanvasXpress chart, which is being hosted by the
Streamlit framework:
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/streamlit_chart_basic.png" align="center" width="600"></a>
Congratulations! You have created a Streamlit CanvasXpress app!
### A Dash Example
[Plotly Dash](https://dash.plotly.com/) is a popular dashboard framework similar to Shiny for Python or R. Dash
applications are Web pages with widgets and elements facilitating the interactive presentation of information. This
example shows how to create a basic Dash application using a CanvasXpress Dash element.
#### Create a Basic Dash App
A basic Dash app provides a means by which:
1. A local development server can be started
1. A function can respond to a URL
First install Dash and CanvasXpress for Python:
```terminal
pip install dash
pip install canvasxpress[dash]
```
Then create a demo file, such as `app.py`, and insert:
```python
from random import random
from dash import Dash, html
from canvasxpress.canvas import CanvasXpress
from canvasxpress.plot import graph
g_app = Dash(__name__)
colors = {
"background": "#111111",
"text": "rgb(127,219,255)",
}
# Application
g_app.layout = html.Div(
style={"backgroundColor": colors["background"]},
children=[
html.H1(
children="Hello Dash",
style={"textAlign": "center", "color": colors["text"]},
),
html.H2(
children=(
"An Example of the Advanced CanvasXpress and CXDashElementFactory"
" Classes for Plotting a CanvasXpress Chart"
),
style={"textAlign": "center", "color": colors["text"]},
),
html.Div(
id="chart-container",
children=[
html.Div(
id="cx-container",
style={"textAlign": "center"},
children=graph(
CanvasXpress(
data={
"y": {
"data": [
[random() % 100 for i in range(5)]
],
"vars": ["A"],
}
},
config={
"background": "rgb(255,255,255)",
"colorScheme": "CanvasXpress",
"graphOrientation": "vertical",
"graphType": "Area",
"objectBorderColor": False,
"plotBox": False,
"plotBoxColor": "rgb(204,204,204)",
"showLegend": False,
"showLegendBorder": True,
"smpLabelRotate": 90,
"smpTitle": "time",
"xAxis": ["A"],
"xAxisTickRightShow": False,
"yAxisTickTopShow": False
},
width=500,
height=500
)
),
),
],
),
],
)
if __name__ == "__main__":
g_app.run_server(debug=True)
```
#### Run the App and View the Page
On the command line, execute:
```terminal
python3 app.py
```
And output similar to the following will be provided:
```terminal
Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)
```
Browsing to `http://127.0.0.1:8050/` will result in a page with a CanvasXpress chart, which is being hosted by the Dash
framework:
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/dash_chart_basic.png" align="center" width="600"></a>
Congratulations! You have created a Plotly Dash CanvasXpress app!
### A Flask Example
[Flask](https://palletsprojects.com/p/flask/) is a popular lean Web development framework for Python based applications.
Flask applications can serve Web pages, RESTful APIs, and similar backend service concepts. This example shows how to
create a basic Flask application that provides a basic Web page with a CanvasXpress chart composed using Python in the
backend.
The concepts in this example equally apply to other frameworks that can serve Web pages, such as Django and Tornado.
#### Create a Basic Flask App
A basic Flask app provides a means by which:
1. A local development server can be started
1. A function can respond to a URL
First install Flask and CanvasXpress for Python:
```terminal
pip install -U Flask canvasxpress
```
Then create a demo file, such as `app.py`, and insert:
```python
# save this as app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def canvasxpress_example():
return "Hello!"
```
On the command line, execute:
```terminal
flask run
```
And output similar to the following will be provided:
```terminal
Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```
Browsing to `http://127.0.0.1:5000/` will result in a page with the text
*Hello!*.
#### Add a Chart
CanvasXpress for Python can be used to define a chart with various attributes and then generate the necessary HTML and
Javascript for proper display in the browser.
Add a `templates` directory to the same location as the `app.py` file, and inside add a file
called `canvasxpress_example.html`. Inside the file add:
```html
<html>
<head>
<meta charset="UTF-8">
<title>Flask CanvasXpress Example</title>
<!-- 2. Include the CanvasXpress library -->
<link
href='https://www.canvasxpress.org/dist/canvasXpress.css'
rel='stylesheet'
type='text/css'
/>
<script
src='https://www.canvasxpress.org/dist/canvasXpress.min.js'
type='text/javascript'>
</script>
<!-- 3. Include script to initialize object -->
<script type="text/javascript">
onReady(function () {
{
{
canvas_source | safe
}
}
})
</script>
</head>
<body>
<!-- 1. DOM element where the visualization will be displayed -->
{{canvas_element|safe}}
</body>
</html>
```
The HTML file, which uses [Jinja syntax](https://palletsprojects.com/p/jinja/) achieves three things:
1. Provides a location for a `<div>` element that marks where the chart will be placed.
1. References the CanvasXpress CSS and JS files needed to illustrate and operate the charts.
1. Provides a location for the Javascript that will replace the chart `<div>` with a working element on page load.
Going back to our Flask app, we can add a basic chart definition with some data to our example function:
```python
from flask import Flask, render_template
from canvasxpress.canvas import CanvasXpress
app = Flask(__name__)
@app.route('/')
def canvasxpress_example():
# Define a CX bar chart with some basic data
chart: CanvasXpress = CanvasXpress(
data={
"y": {
"vars": ["Gene1"],
"smps": ["Smp1", "Smp2", "Smp3"],
"data": [[10, 35, 88]]
}
},
config={
"graphType": "Bar"
}
)
# Get the HTML parts for use in our Web page:
html_parts: dict = chart.render_to_html_parts()
# Return a Web page based on canvasxpress_example.html and our HTML parts
return render_template(
"canvasxpress_example.html",
canvas_element=html_parts["cx_canvas"],
canvas_source=html_parts["cx_js"]
)
```
#### Run the App and View the Page
Rerun the flask app on the command line and browse to the indicated IP and URL. A page similar to the following will be
displayed:
<img src="https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/flask_bar_chart_basic.png" align="center" width="600"></a>
Congratulations! You have created a Flask CanvasXpress app!
Raw data
{
"_id": null,
"home_page": "https://github.com/docinfosci/canvasxpress-python.git",
"name": "canvasxpress",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "Dr. Isaac Neuhaus for CanvasXpress JS, PHP, and R; Dr. Constance M. Brett for R; Dr. Todd C. Brett for Python and Dash; and Dr. Jennifer Walker for Python.",
"author_email": "todd@aggregate-genius.com",
"download_url": "https://files.pythonhosted.org/packages/d8/d9/4b88caf8349e324ad68d613d9afb71ddc04c48403f40d2438d7d5aa4c311/canvasxpress-2024.12.16.170658.tar.gz",
"platform": null,
"description": "# CanvasXpress for Python\n\n<a href=\"https://www.canvasxpress.org\">\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/images/hexagon.png\" align=\"left\" width=\"175\" style=\"vertical-align:middle;margin:10px 10px\"> \n</a>\n<br>\n\n[***CanvasXpress***](https://www.canvasxpress.org) was developed as the core visualization component for bioinformatics\nand systems biology analysis at Bristol-Myers Squibb. It supports a large number\nof [visualizations ](https://www.canvasxpress.org/examples.html)\nto display scientific and non-scientific data. ***CanvasXpress*** also includes a simple and unobtrusive\n[user interface](https://www.canvasxpress.org/docs/interface.html) to explore complex data sets, a sophisticated and\nunique mechanism to keep track of all user customization for\n[Reproducible Research ](https://www.canvasxpress.org/docs/audit.html) purposes, as well as an 'out of the box'\nbroadcasting capability to synchronize selected data points across all ***CanvasXpress*** plots in a page. Data can be\neasily sorted, grouped, transposed, transformed or clustered dynamically. The fully customizable mouse events as well as\nthe zooming, panning and drag-and-drop capabilities are features that make this library unique in its class.\n\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/images/sample_graphs.png\" align=\"center\" width=\"726\"></a>\n\n***CanvasXpress*** can be used for native Python integration for the following environments:\n\n- [Shiny for Python](https://shiny.posit.co/py/)\n- [Streamlit](https://streamlit.io/)\n- [Plotly Dash](https://dash.plotly.com/)\n- [Jupyter](https://jupyter.org/)\n- [Flask](https://flask.palletsprojects.com/en/1.1.x/)\n- [Django](https://www.djangoproject.com/)\n\nThe RStudio IDE Viewer is also used when running code chunks in Jupyter, Quarto, and RMD Python code chunks.\n\nThis ***CanvasXpress*** Python package is maintained by [Dr. Todd C. Brett](https://github.com/docinfosci), with support \nfrom [Aggregate Genius Inc.](https://www.aggregate-genius.com), in cooperation with Dr. Isaac Neuhaus and the \n***CanvasXpress*** team.\n\n## Project Status\n\n[![Release](https://img.shields.io/pypi/v/canvasxpress.svg)](https://pypi.org/project/canvasxpress)\n[![Compatibility](https://img.shields.io/pypi/pyversions/canvasxpress.svg)](https://pypi.org/project/canvasxpress)\n[![Implementations](https://img.shields.io/pypi/implementation/canvasxpress.svg)](https://pypi.org/project/canvasxpress)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/canvasxpress)](https://pypi.org/project/canvasxpress)\n[![docinfosci](https://circleci.com/gh/docinfosci/canvasxpress-python/tree/main.svg?style=shield)](https://circleci.com/gh/docinfosci/canvasxpress-python/?branch=main)\n[![Coverage Status](https://coveralls.io/repos/github/docinfosci/canvasxpress-python/badge.svg?branch=main)](https://coveralls.io/github/docinfosci/canvasxpress-python?branch=main)\n[![Activity](https://img.shields.io/github/last-commit/docinfosci/canvasxpress-python/develop)](https://github.com/docinfosci/canvasxpress-python)\n\n## Documentation, Installation, and Usage\n\n### Documentation\n\nDocumentation is maintained at [CanvasXpress.org](https://www.canvasxpress.org) and LinkedIn:\n\n- [Introduction to CanvasXpress for Python](https://www.linkedin.com/pulse/introducing-canvasxpress-python-todd-brett-hew0f/?trackingId=G8kTE2QyRH%2BrcVSzxJc8Hg%3D%3D)\n\n### Installation\n\nCanvasXpress for Python can be installed using _pip_:\n\nThe essential CanvasXpress package, for use with the CLI or flask and similar environments, can be installed using:\n\n```terminal\npip install canvasxpress\n```\n\nor\n\n```terminal\npip install \"canvasxpress[core]\"\n```\n\nIn addition to _core_, the following additional targets can be used:\n\n- _jupyter_ - installs additional packages to support rendering in Jupyter, Quarto, and IPython documents\n- _dash_ - installs additional packages to support rendering in Plotly Dash applications\n- _streamlit_ - installs additional packages to support rendering in Snowflake Streamlit applications\n- _shiny_ - installs additional packages to support rendering in Posit Shiny for Python applications\n- _rstudio_ - installs additional packages to support rendering in the Posit RStudio IDE Viewer, plus includes the same packages for jupyter and shiny\n- _all_ - installs all additional packages to support rendering in any supported document or application\n\n### Drawing Charts\n\nThe `CanvasXpress` object defines what a chart should contain and how it should be formatted, but rendering the chart\nis performed by the functions `graph()` and `show_in_browser()`. \n\nTo use `graph()` import it from `canvasxpress.plot` and then call it by passing a `CanvasXpress` object. For example, a\nQuarto, RMD, or Jupyter Notebook code chunk could be:\n\n```python\nfrom random import random\n\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.plot import graph\n\ngraph(\n CanvasXpress(\n data={\n \"y\": {\n \"data\": [\n [random() % 100 for i in range(20)]\n ],\n \"vars\": [\"A\"],\n }\n },\n config={\n \"background\": \"rgb(255,255,255)\",\n \"colorScheme\": \"CanvasXpress\",\n \"graphOrientation\": \"vertical\",\n \"graphType\": \"Area\",\n \"objectBorderColor\": False,\n \"plotBox\": False,\n \"plotBoxColor\": \"rgb(204,204,204)\",\n \"showLegend\": False,\n \"showLegendBorder\": True,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"time\",\n \"xAxis\": [\"A\"],\n \"xAxisTickRightShow\": False,\n \"yAxisTickTopShow\": False\n },\n width=609,\n height=609\n )\n)\n```\n\nSome application frameworks, such as _Shiny for Python_ and _Plotly Dash_, expect an object to be rendered to the \nframework as part of the reactive flow. In these contexts, the `graph()` function creates an appropriate object\nand returns it. That value can be assigned to a variable to be returned at a later point in the code, or be \nimmediately returned. See the Shiny for Python and Dash examples for specific usage.\n\n`show_in_browser()` is similar to `graph()` except that it opens a browser window on the local system and displays the \nchart. It's used to facilitate learning and debugging.\n\n`graph()` does a good job of determining the runtime context to choose how the chart should be rendered, but in the \ncase installed packages or runtime configurations confuse the function an environment variable can be set to override\nhow `graph()` performs the rendering. Set `CANVASXPRESS_TARGET_CONTEXT` to be one of these values as appropriate for\nthis situation (and don't forget to pip install the necessary package support):\n\n- rstudio\n- shiny\n- jupyter\n- dash\n- streamlit\n- browser\n\nFor example:\n\n```python\nfrom os import environ\nenviron[\"CANVASXPRESS_TARGET_CONTEXT\"] = \"jupyter\"\n```\n\nor via a shell (_bash_ example provided):\n\n```shell\nexport CANVASXPRESS_TARGET_CONTEXT=\"jupyter\"\n```\n\n### Default and Pinned CanvasXpress JavaScript Editions\n\nCanvasXpress for Python generates JavaScript that assumes use of the latest available edition of CanvasXpress for\nJavaScript, but it can be set to use a specific edition.\n\nReview this site for available versions:\nhttps://cdnjs.com/libraries/canvasXpress\n\nThe desired version is expressed as a `str`. Prior to generating a CanvasXpress chart use the following code to set \nthe edition that shall be used:\n\n```python\nfrom canvasxpress.canvas import CanvasXpress\nCanvasXpress.set_cdn_edition(\"48.3\") # Or whatever available version is desired.\n```\n\nTo use the default edition once again during the runtime session set the value to `None`.\n\nThis is the best way to assure a specific chart behavior for production application releases; however, once set any\nnew JavaScript edition features or fixes will not be available until the code is removed or a different version is set.\n\n### Customizing Charts\n\nGenerally speaking, a `CanvasXpress` object accepts the following parameters:\n\n#### render_to\n\n`render_to` is a `str` value that identifies the chart when rendered into HTML. JavaScript functions can use this ID\nto access the chart and perform CanvasXpress operations within the browser. Omitting `render_to` or setting it to \n`None` will make the `CanvasXpress` object assume an anonymous mode in which a new GUID will be generated each time \n`graph()` is called. If the chart will not be maniluated using JavaScript in the browser it is fine for charts to be anonymous.\n\n__NOTE:__ React environments regularly destroy and rebuild objects as the page is updated. In these environments it is\npossible for the timing of object destruction and JavaScript execution to cause a crash. The best defense is to either \nuse anonymous mode, or if an ID must be known then a unique identifier should be set each time `graph()` is called. In\nthis manner an ID for a chart in the middle of being recreated is never referenced. For example:\n\n```python\nchart = CanvasXpress(...)\nchart.render_to = str(guid4()).replace(\"-\", \"_\")\nreturn graph(chart)\n```\n\nPlotly's Dash framework uses React, and Dash applications should consider using only anonymous charts or assigning\nunique values as the ID similar to the above code. Shiny for Python does not seem to suffer from this challenge.\n\n#### data\n\n`data` sets the chart's data and metadata. This is an involved topic, and the [introductory article](https://www.linkedin.com/pulse/introducing-canvasxpress-python-todd-brett-hew0f/?trackingId=G8kTE2QyRH%2BrcVSzxJc8Hg%3D%3D)\nis an excellent read to understand how data should be shaped. In general, data will be a `dict`, Web URL, or `str`.\n\nData dict example:\n\n```python\ndata_for_use_in_chart = {\n \"y\": {\n \"data\": [\n [random() % 100 for i in range(20)]\n ],\n \"vars\": [\"A\"],\n }\n}\n```\n\nData URL example:\n\n```python\ndata_for_use_in_chart = \"https://corgis-edu.github.io/corgis/datasets/csv/state_demographics/state_demographics.csv\"\n```\n\nData text (CSV) example:\n\n```python\ndata_for_use_in_chart = \"\"\"\n\"State\",\"Population.Population Percent Change\",\"Population.2014 Population\"\n\"Connecticut\",\"-10.2\",\"3605944\"\n\"Delaware\",\"8.4\",\"989948\"\n\"\"\"\n```\n\n#### config\n\n`config` describes the chart's formatting. It is a `dict` in which properties are specified and assigned values. All\nof the values must be compliant with Python's `json.dumps()` function. For example:\n\n```python\nconfig={\n \"background\": \"rgb(255,255,255)\",\n \"colorScheme\": \"CanvasXpress\",\n \"graphOrientation\": \"vertical\",\n \"graphType\": \"Area\",\n \"objectBorderColor\": False,\n \"plotBox\": False,\n \"plotBoxColor\": \"rgb(204,204,204)\",\n \"showLegend\": False,\n \"showLegendBorder\": True,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"time\",\n \"xAxis\": [\"A\"],\n \"xAxisTickRightShow\": False,\n \"yAxisTickTopShow\": False\n},\n```\n\n#### width and height\n\n`width` and `height` specify the chart's dimensions as pixels. If ommitted the CanvasXpress edition active for the \nbrowser will assign default values, such as 500px by 500px.\n\n#### Javascript Events\n\nCanvasXpress provides support for Javascript events via hook functions that are called when events occur, such as mouse \nmovement or clicks. These events are supported via the canvasxpress.js sub-package. `CXEvent` objects hold the \nJavascript instructions for Web events. An example event for graph clicks with popup information is:\n\n```python\nfrom canvasxpress.js.function import CXEvent\n\nCXEvent(\n id=\"click\",\n script=\"\"\"\n var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];\n t.showInfoSpan(e, s);\n \"\"\"\n)\n```\n\nThe general JavaScript template of a CanvasXpress Javascript hook function is:\n\n```javascript\nfunction (o, e, t) {\n // script logic goes here\n};\n```\n\n`CXEvent` objects can be provided as a single object or as a list. Here's an example of an event the provides \nadditional information about chart data upon a user click:\n\n```python\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.plot import graph\nfrom canvasxpress.js.function import CXEvent\n\ngraph(\n CanvasXpress(\n render_to=\"example_chart\",\n data={\n \"y\": {\n \"vars\": [\"Gene1\"],\n \"smps\": [\"Smp1\", \"Smp2\", \"Smp3\"],\n \"data\": [[10, 35, 88]]\n }\n },\n config={\n \"graphOrientation\": \"vertical\",\n \"graphType\": \"Bar\",\n \"showLegend\": False,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"Samples\",\n \"theme\": \"CanvasXpress\",\n \"title\": \"Bar Graph Title\",\n \"xAxisTitle\": \"Value\"\n },\n events=[\n CXEvent(\n id=\"click\",\n script=\"\"\"\n var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];\n t.showInfoSpan(e, s);\n \"\"\"\n ),\n ]\n )\n)\n```\n\n## Converting to and from Reproducible JSON\n\nCanvasXpress for Python can also convert to and from reproducible JSONs usable with the JavaScript and R editions of the\nlibrary. `convert_to_reproducible_json` takes an existing CanvasXpress object and provides a `str` copy of the JSON, \nwhich can then be logged for debugging or saved to disk for use elsewhere. `convert_from_reproducible_json` does the\nopposite by taking a reproducible JSON `str` and providing the CanvasXpress object equivalent.\n\n_Note: Events are not currently supported for import. This will be provided in a future edition. Export supports events._\n\nFor example, do the following to see the JSON in the Python console:\n\n```python\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.plot import convert_to_reproducible_json\nfrom canvasxpress.js.function import CXEvent\n\nprint(\n convert_to_reproducible_json(\n CanvasXpress(\n render_to=\"example_chart\",\n data={\n \"y\": {\n \"vars\": [\"Gene1\"],\n \"smps\": [\"Smp1\", \"Smp2\", \"Smp3\"],\n \"data\": [[10, 35, 88]]\n }\n },\n config={\n \"graphOrientation\": \"vertical\",\n \"graphType\": \"Bar\",\n \"showLegend\": False,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"Samples\",\n \"theme\": \"CanvasXpress\",\n \"title\": \"Bar Graph Title\",\n \"xAxisTitle\": \"Value\"\n },\n events=[\n CXEvent(\n id=\"click\",\n script=\"\"\"\n var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];\n t.showInfoSpan(e, s);\n \"\"\"\n ),\n ]\n )\n )\n)\n```\n\nThe console would display:\n\n```text\n{\n \"renderTo\": \"example_chart\",\n \"data\": {\"y\": {\"vars\": [\"Gene1\"], \"smps\": [\"Smp1\", \"Smp2\", \"Smp3\"], \"data\": [[10, 35, 88]]}, \"x\": {}, \"z\": {}},\n \"config\": {\"graphOrientation\": \"vertical\", \"graphType\": \"Bar\", \"showLegend\": false, \"smpLabelRotate\": 90, \"smpTitle\": \"Samples\", \"theme\": \"CanvasXpress\", \"title\": \"Bar Graph Title\", \"xAxisTitle\": \"Value\"},\n \"afterRender\": [],\n \"otherParams\": {},\n \"events\": {'click': function(o, e, t){\n var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];\n t.showInfoSpan(e, s);\n }},\n \"width\": 500,\n \"height\": 500\n}\n```\n\nThis text could be saved to a file, such as `example.json`, and then dragged onto a CanvasXpress chart in a browser\nto load the equivalent chart. In fact, CanvasXpress for Python uses the core functionality producing JSON output to \nmake charts available in contexts such as Dash and Shiny.\n\n## Application, NoteBook, and Console Examples\n\n### Rendering Charts in the RStudio IDE Viewer Pane \n\nThe RStudio IDE's Viewer panel is now supported for rendering interactive charts in the Viewer! When the `graph()`\nfunction is called it detects that RStudio is running and renders the chart in the Viewer instead of a document, \nsuch as for Quarto code chunks. However, if the document is a Quarto or RMD file and the appropriate HTML (etc.)\ngeneration is performed then the CanvasXpress charts will be embedded in the generated output file as normal.\n\n### A Basic Python Script / Console Example\n\nCharts can be defined in scripts or a console session and then displayed using the default browser, assuming that a\ngraphical browser with Javascript support is available on the host system. To do so use the `show_in_browser()`\nfunction instead of graph()`.\n\n```python\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.plot import show_in_browser\n\nif __name__ == \"__main__\":\n # Define a CX bar chart with some basic data\n chart: CanvasXpress = CanvasXpress(\n data={\n \"y\": {\n \"vars\": [\"Gene1\"],\n \"smps\": [\"Smp1\", \"Smp2\", \"Smp3\"],\n \"data\": [[10, 35, 88]]\n }\n },\n config={\n \"graphType\": \"Bar\"\n }\n )\n\n # Display the chart in its own Web page\n show_in_browser(chart)\n```\n\nUpon running the example the following chart will be displayed on systems such as MacOS X, Windows, and Linux with\ngraphical systems:\n\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/flask_bar_chart_basic.png\" align=\"center\" width=\"600\"></a>\n\n### A Shiny for Python Example\n\n[Shiny for Python](https://shiny.posit.co/py/) is a new dashboard framework inspired by the highly successful Shiny for\nR framework produced by Posit (formerly RStudio). This example shows how to create a basic Shiny for Python application\nusing a CanvasXpress Shiny element.\n\nA basic Shiny for Python app provides a means by which:\n\n1. A local development server can be started\n1. A function can respond to input or draw an initial UI\n\nFirst install Shiny for Python and CanvasXpress for Python:\n\n```terminal\npip install shiny\npip install canvasxpress[shiny]\n```\n\nThen create a demo file, such as `app.py`, and insert:\n\n```python\nfrom random import random\n\nfrom shiny import App, ui, render, reactive\n\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.render.shiny import output_canvasxpress\nfrom canvasxpress.plot import graph\n\napp_ui = ui.page_fluid(\n ui.row(\n ui.input_slider(\n \"points_desired\",\n \"Points\",\n min=0,\n max=100,\n value=0,\n ),\n ),\n ui.row(\n output_canvasxpress(\"chart_view\"),\n )\n)\n\n\ndef server(input, output, session):\n @render.ui\n @reactive.event(input.points_desired)\n def chart_view():\n return graph(\n CanvasXpress(\n data={\n \"y\": {\n \"data\": [\n [random() % 100 for i in range(input.points_desired())]\n ],\n \"vars\": [\"A\"],\n }\n },\n config={\n \"background\": \"rgb(255,255,255)\",\n \"colorScheme\": \"CanvasXpress\",\n \"graphOrientation\": \"vertical\",\n \"graphType\": \"Area\",\n \"objectBorderColor\": False,\n \"plotBox\": False,\n \"plotBoxColor\": \"rgb(204,204,204)\",\n \"showLegend\": False,\n \"showLegendBorder\": True,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"time\",\n \"xAxis\": [\"A\"],\n \"xAxisTickRightShow\": False,\n \"yAxisTickTopShow\": False\n },\n width=500,\n height=500\n )\n )\n\n\napp = App(app_ui, server)\n```\n\n#### Run the App and View the Page\n\nOn the command line, execute:\n\n```terminal\nshiny run --reload --launch-browser app.py\n```\n\nAnd output similar to the following will be provided:\n\n```terminal\nUvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\nBrowsing to `http://localhost:8000/` will result in a page with a CanvasXpress chart, which is being hosted by the Shiny\nfor Python framework:\n\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/shiny_chart_example.png\" align=\"center\" width=\"600\"></a>\n\nCongratulations! You have created a Shiny for Python CanvasXpress app!\n\n### A Streamlit Example\n\n[Streamlit](https://streamlit.io) is a popular dashboard framework that is simplified compared to Dash and Shiny, but\njust as powerful in terms of reactivity and extensions. This example shows how to create a basic Streamlit application\nusing a CanvasXpress Streamlit element.\n\nA basic Streamlit app provides a means by which:\n\n1. A local development server can be started\n1. A function can respond to a URL\n\nFirst install Streamlit and CanvasXpress for Python:\n\n```terminal\npip install streamlit\npip install canvasxpress[streamlit]\n```\n\nThen create a demo file, such as `app.py`, and insert:\n\n```python\nimport random\n\nimport streamlit as st\n\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.plot import graph\n\n# A basic bar chart. It's anonymous, so no render_to. Data is added during the draw phase.\nchord_chart = CanvasXpress(\n config={\n \"graphOrientation\": \"vertical\",\n \"plotBox\": True,\n \"showLegend\": False,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"Samples\",\n \"theme\": \"CanvasXpress\",\n \"title\": \"Bar Graph Title\",\n \"xAxis\": [\"V1\"],\n \"xAxisTitle\": \"Value\",\n \"graphType\": \"Bar\"\n },\n width=500,\n height=500\n)\n\n# Write the UI to the browser\n# This code will be re-executed with each click of the button\n\n# Name the theme\nst.title('CanvasXpress in Streamlit!')\n\n# Some columns to organize the button and chart\ncolumn1, column2 = st.columns(2)\n\n# A column with our data generator button\ncolumn1.write(\n # This has no associated action, so by default it triggers a redraw of the UI.\n st.button(\"Generate New Data\")\n)\n\n# Another column with the chart displayed\n# With each redraw generate new random values\nchord_chart.data = {\n \"y\": {\n \"vars\": [\"V1\"],\n \"smps\": [\"S1\", \"S2\", \"S3\"],\n \"data\": [\n [\n random.randint(100, 10000),\n random.randint(100, 10000),\n random.randint(100, 10000),\n ]\n ]\n }\n}\ncolumn2.write(\n # This plots the CanvasXpress chart into the UI.\n graph(chord_chart)\n)\n```\n\n#### Run the App and View the Page\n\nOn the command line, execute:\n\n```terminal\nstreamlit run app.py\n```\n\nAnd output similar to the following will be provided:\n\n```terminal\nRunning on http://localhost:8501/ (Press CTRL+C to quit)\n```\n\nBrowsing to `http://localhost:8501/` will result in a page with a CanvasXpress chart, which is being hosted by the\nStreamlit framework:\n\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/streamlit_chart_basic.png\" align=\"center\" width=\"600\"></a>\n\nCongratulations! You have created a Streamlit CanvasXpress app!\n\n### A Dash Example\n\n[Plotly Dash](https://dash.plotly.com/) is a popular dashboard framework similar to Shiny for Python or R. Dash\napplications are Web pages with widgets and elements facilitating the interactive presentation of information. This\nexample shows how to create a basic Dash application using a CanvasXpress Dash element.\n\n#### Create a Basic Dash App\n\nA basic Dash app provides a means by which:\n\n1. A local development server can be started\n1. A function can respond to a URL\n\nFirst install Dash and CanvasXpress for Python:\n\n```terminal\npip install dash\npip install canvasxpress[dash]\n```\n\nThen create a demo file, such as `app.py`, and insert:\n\n```python\nfrom random import random\n\nfrom dash import Dash, html\n\nfrom canvasxpress.canvas import CanvasXpress\nfrom canvasxpress.plot import graph\n\ng_app = Dash(__name__)\n\ncolors = {\n \"background\": \"#111111\",\n \"text\": \"rgb(127,219,255)\",\n}\n\n# Application\ng_app.layout = html.Div(\n style={\"backgroundColor\": colors[\"background\"]},\n children=[\n html.H1(\n children=\"Hello Dash\",\n style={\"textAlign\": \"center\", \"color\": colors[\"text\"]},\n ),\n html.H2(\n children=(\n \"An Example of the Advanced CanvasXpress and CXDashElementFactory\"\n \" Classes for Plotting a CanvasXpress Chart\"\n ),\n style={\"textAlign\": \"center\", \"color\": colors[\"text\"]},\n ),\n html.Div(\n id=\"chart-container\",\n children=[\n html.Div(\n id=\"cx-container\",\n style={\"textAlign\": \"center\"},\n children=graph(\n CanvasXpress(\n data={\n \"y\": {\n \"data\": [\n [random() % 100 for i in range(5)]\n ],\n \"vars\": [\"A\"],\n }\n },\n config={\n \"background\": \"rgb(255,255,255)\",\n \"colorScheme\": \"CanvasXpress\",\n \"graphOrientation\": \"vertical\",\n \"graphType\": \"Area\",\n \"objectBorderColor\": False,\n \"plotBox\": False,\n \"plotBoxColor\": \"rgb(204,204,204)\",\n \"showLegend\": False,\n \"showLegendBorder\": True,\n \"smpLabelRotate\": 90,\n \"smpTitle\": \"time\",\n \"xAxis\": [\"A\"],\n \"xAxisTickRightShow\": False,\n \"yAxisTickTopShow\": False\n },\n width=500,\n height=500\n )\n ),\n ),\n ],\n ),\n ],\n)\n\nif __name__ == \"__main__\":\n g_app.run_server(debug=True)\n```\n\n#### Run the App and View the Page\n\nOn the command line, execute:\n\n```terminal\npython3 app.py\n```\n\nAnd output similar to the following will be provided:\n\n```terminal\nRunning on http://127.0.0.1:8050/ (Press CTRL+C to quit)\n```\n\nBrowsing to `http://127.0.0.1:8050/` will result in a page with a CanvasXpress chart, which is being hosted by the Dash\nframework:\n\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/dash_chart_basic.png\" align=\"center\" width=\"600\"></a>\n\nCongratulations! You have created a Plotly Dash CanvasXpress app!\n\n### A Flask Example\n\n[Flask](https://palletsprojects.com/p/flask/) is a popular lean Web development framework for Python based applications.\nFlask applications can serve Web pages, RESTful APIs, and similar backend service concepts. This example shows how to\ncreate a basic Flask application that provides a basic Web page with a CanvasXpress chart composed using Python in the\nbackend.\n\nThe concepts in this example equally apply to other frameworks that can serve Web pages, such as Django and Tornado.\n\n#### Create a Basic Flask App\n\nA basic Flask app provides a means by which:\n\n1. A local development server can be started\n1. A function can respond to a URL\n\nFirst install Flask and CanvasXpress for Python:\n\n```terminal\npip install -U Flask canvasxpress\n```\n\nThen create a demo file, such as `app.py`, and insert:\n\n```python\n# save this as app.py\nfrom flask import Flask\n\napp = Flask(__name__)\n\n\n@app.route('/')\ndef canvasxpress_example():\n return \"Hello!\"\n```\n\nOn the command line, execute:\n\n```terminal\nflask run\n```\n\nAnd output similar to the following will be provided:\n\n```terminal\nRunning on http://127.0.0.1:5000/ (Press CTRL+C to quit)\n```\n\nBrowsing to `http://127.0.0.1:5000/` will result in a page with the text\n*Hello!*.\n\n#### Add a Chart\n\nCanvasXpress for Python can be used to define a chart with various attributes and then generate the necessary HTML and\nJavascript for proper display in the browser.\n\nAdd a `templates` directory to the same location as the `app.py` file, and inside add a file\ncalled `canvasxpress_example.html`. Inside the file add:\n\n```html\n\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <title>Flask CanvasXpress Example</title>\n\n <!-- 2. Include the CanvasXpress library -->\n <link\n href='https://www.canvasxpress.org/dist/canvasXpress.css'\n rel='stylesheet'\n type='text/css'\n />\n <script\n src='https://www.canvasxpress.org/dist/canvasXpress.min.js'\n type='text/javascript'>\n </script>\n\n <!-- 3. Include script to initialize object -->\n <script type=\"text/javascript\">\n onReady(function () {\n {\n {\n canvas_source | safe\n }\n }\n })\n </script>\n\n</head>\n<body>\n\n<!-- 1. DOM element where the visualization will be displayed -->\n{{canvas_element|safe}}\n\n</body>\n</html>\n```\n\nThe HTML file, which uses [Jinja syntax](https://palletsprojects.com/p/jinja/) achieves three things:\n\n1. Provides a location for a `<div>` element that marks where the chart will be placed.\n1. References the CanvasXpress CSS and JS files needed to illustrate and operate the charts.\n1. Provides a location for the Javascript that will replace the chart `<div>` with a working element on page load.\n\nGoing back to our Flask app, we can add a basic chart definition with some data to our example function:\n\n```python\nfrom flask import Flask, render_template\nfrom canvasxpress.canvas import CanvasXpress\n\napp = Flask(__name__)\n\n\n@app.route('/')\ndef canvasxpress_example():\n # Define a CX bar chart with some basic data\n chart: CanvasXpress = CanvasXpress(\n data={\n \"y\": {\n \"vars\": [\"Gene1\"],\n \"smps\": [\"Smp1\", \"Smp2\", \"Smp3\"],\n \"data\": [[10, 35, 88]]\n }\n },\n config={\n \"graphType\": \"Bar\"\n }\n )\n\n # Get the HTML parts for use in our Web page:\n html_parts: dict = chart.render_to_html_parts()\n\n # Return a Web page based on canvasxpress_example.html and our HTML parts\n return render_template(\n \"canvasxpress_example.html\",\n canvas_element=html_parts[\"cx_canvas\"],\n canvas_source=html_parts[\"cx_js\"]\n )\n```\n\n#### Run the App and View the Page\n\nRerun the flask app on the command line and browse to the indicated IP and URL. A page similar to the following will be\ndisplayed:\n\n<img src=\"https://raw.githubusercontent.com/docinfosci/canvasxpress-python/main/readme/examples/flask_bar_chart_basic.png\" align=\"center\" width=\"600\"></a>\n\nCongratulations! You have created a Flask CanvasXpress app!\n",
"bugtrack_url": null,
"license": "Copyright 2020 to 2024 CanvasXpress all rights reserved",
"summary": "CanvasXpress for Python",
"version": "2024.12.16.170658",
"project_urls": {
"Documentation": "https://canvasxpress-python.readthedocs.io",
"Homepage": "https://github.com/docinfosci/canvasxpress-python.git"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d8d94b88caf8349e324ad68d613d9afb71ddc04c48403f40d2438d7d5aa4c311",
"md5": "39747ddf38f03d74c406e5ea160bad92",
"sha256": "bcab23041308e2f648e639a8337a2e6cd68258f9dc880cf718d7de617b3d5e17"
},
"downloads": -1,
"filename": "canvasxpress-2024.12.16.170658.tar.gz",
"has_sig": false,
"md5_digest": "39747ddf38f03d74c406e5ea160bad92",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 134148,
"upload_time": "2024-12-16T17:06:59",
"upload_time_iso_8601": "2024-12-16T17:06:59.386655Z",
"url": "https://files.pythonhosted.org/packages/d8/d9/4b88caf8349e324ad68d613d9afb71ddc04c48403f40d2438d7d5aa4c311/canvasxpress-2024.12.16.170658.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-16 17:06:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "docinfosci",
"github_project": "canvasxpress-python",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"circle": true,
"requirements": [
{
"name": "deepdiff",
"specs": []
},
{
"name": "gitpython",
"specs": [
[
">=",
"3"
]
]
},
{
"name": "pytz",
"specs": [
[
">=",
"2020.1"
]
]
},
{
"name": "pandas",
"specs": [
[
">=",
"1.1.5"
]
]
},
{
"name": "requests",
"specs": [
[
">=",
"2"
]
]
},
{
"name": "Deprecated",
"specs": [
[
">=",
"1.2.12"
]
]
},
{
"name": "jupyter",
"specs": []
},
{
"name": "IPython",
"specs": [
[
">=",
"7"
]
]
},
{
"name": "beautifulsoup4",
"specs": [
[
">=",
"4"
]
]
},
{
"name": "htmlmin",
"specs": [
[
">=",
"0.1.12"
]
]
},
{
"name": "requests",
"specs": []
},
{
"name": "dash",
"specs": []
},
{
"name": "streamlit",
"specs": []
},
{
"name": "shiny",
"specs": []
},
{
"name": "htmltools",
"specs": []
},
{
"name": "ipywidgets",
"specs": []
},
{
"name": "shinywidgets",
"specs": []
},
{
"name": "rpy2",
"specs": []
}
],
"lcname": "canvasxpress"
}