Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plotly standard now fully supported #79

Merged
merged 6 commits into from
May 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 60 additions & 7 deletions src-backend/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,24 +132,68 @@ export class ContentHelpers{
// The output is rich
} else if('data' in content){
let data = content.data;
let chosenType = this.chooseTypeFromComplexData(data);
let output = data[chosenType];
if(typeof output === 'string'){
this.contentTmp.push(new CardOutput(chosenType, output));
}
this.contentTmp.push(this.interpretRich(data));
// The code could not be executed, an error was returned
} else if(['ename', 'evalue', 'traceback'].every(value => value in content)) {
let ename = content['ename'];
let evalue = content['evalue'];
this.getMissingModule(evalue as string);
let traceback = (content['traceback'] as string[]).join('\n');
this.contentTmp.push(new CardOutput('error', traceback));
}
}

static interpretRich(data: JSONValue): CardOutput{
let chosenType = this.chooseTypeFromComplexData(data);
let output: string = '';

if(chosenType === 'application/vnd.plotly.v1+json'){
let plotlyJson = data[chosenType];
if(ContentHelpers.validateData(plotlyJson, 'data')){
let guid = this.generateGuid();
output =
'<div id="' + guid + '" style="height: 525px; width: 100%;" class="plotly-graph-div">'
+ '</div><script type="text/javascript">require(["plotly"], function(Plotly)'
+ '{ window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("'
+ guid + '",' + JSON.stringify(plotlyJson.data) + ', {}, {"showLink": true, "linkText": "Export to plot.ly"})});</script>';
}
chosenType = 'text/html';
}
else{
output = data[chosenType];
}
return new CardOutput(chosenType, output);
}

static getMissingModule(evalue: string){
let moduleMatch = evalue.match(/No module named \'(.+?)\'/);
if(moduleMatch){
let module = moduleMatch[1].replace(/\'/g, '');
vscode.window.showInformationMessage('Jupyter requires the module \'' + moduleMatch[1] + '\' to be installed. Install now?', 'Install')
.then(data => {
if(data) {
this.installMissingModule(module);
}
});
}
}

static installMissingModule(module: string){
if (module) {
let terminal = vscode.window.createTerminal('pip');
terminal.show();
terminal.sendText('pip install '+module, true);
}
}

static chooseTypeFromComplexData(data: JSONValue) {
let validDataTypes =
['text/html', 'image/svg+xml', 'image/png', 'image/jpeg', 'text/markdown', 'application/pdf',
'text/latex', 'application/javascript', 'application/json', 'text/plain']
['application/vnd.jupyter', 'application/vnd.jupyter.cells',
'application/vnd.jupyter.dragindex', 'application/x-ipynb+json',
'application/geo+json', 'application/vnd.plotly.v1+json',
'application/vdom.v1+json', 'text/html', 'image/svg+xml',
'image/png', 'image/jpeg', 'text/markdown', 'application/pdf',
'text/latex', 'application/json', 'text/plain']
.filter(dataType => this.validateData(data, dataType));
return validDataTypes[0];
}
Expand All @@ -159,4 +203,13 @@ export class ContentHelpers{
this.contentTmp = [];
this.id++;
}

static generateGuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
}
1 change: 1 addition & 0 deletions src-frontend/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script src="assets/require.js"></script>
<script>requirejs.config({paths: { 'plotly': ['https://cdn.plot.ly/plotly-latest.min']},});if(!window.Plotly) {{require(['plotly'],function(plotly) {window.Plotly=plotly;});}}</script>
</head>
<body>
<app-root></app-root>
Expand Down
75 changes: 75 additions & 0 deletions test/samples/python_samples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

from plotly.graph_objs import Scatter, Figure, Layout

init_notebook_mode(connected=True)

iplot([{"x": [1, 2, 3], "y": [3, 1, 6]}])



from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

import plotly.graph_objs as go

import pandas as pd

# Read data from a csv
z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')

data = [
go.Surface(
z=z_data.as_matrix()
)
]
layout = go.Layout(
title='Mt Bruno Elevation',
autosize=False,
width=500,
height=500,
margin=dict(
l=65,
r=50,
b=65,
t=90
)
)
fig = go.Figure(data=data, layout=layout)
iplot(fig)



from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

import plotly.graph_objs as go


z1 = [
[8.83,8.89,8.81,8.87,8.9,8.87],
[8.89,8.94,8.85,8.94,8.96,8.92],
[8.84,8.9,8.82,8.92,8.93,8.91],
[8.79,8.85,8.79,8.9,8.94,8.92],
[8.79,8.88,8.81,8.9,8.95,8.92],
[8.8,8.82,8.78,8.91,8.94,8.92],
[8.75,8.78,8.77,8.91,8.95,8.92],
[8.8,8.8,8.77,8.91,8.95,8.94],
[8.74,8.81,8.76,8.93,8.98,8.99],
[8.89,8.99,8.92,9.1,9.13,9.11],
[8.97,8.97,8.91,9.09,9.11,9.11],
[9.04,9.08,9.05,9.25,9.28,9.27],
[9,9.01,9,9.2,9.23,9.2],
[8.99,8.99,8.98,9.18,9.2,9.19],
[8.93,8.97,8.97,9.18,9.2,9.18]
]

z2 = [[zij+1 for zij in zi] for zi in z1]
z3 = [[zij-1 for zij in zi] for zi in z1]

data = [
go.Surface(z=z1),
go.Surface(z=z2, showscale=False, opacity=0.9),
go.Surface(z=z3, showscale=False, opacity=0.9)

]

iplot(data,filename='python-docs/multiple-surfaces')