Skip to content

Commit 35f8f17

Browse files
committed
Started implementing plotting module
1 parent 3064b5a commit 35f8f17

3 files changed

Lines changed: 197 additions & 5 deletions

File tree

src/danfojs-base/core/series.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import Dt from './datetime';
2626
import dummyEncode from "../transformers/encoders/dummy.encoder";
2727
import DataFrame from "./frame";
2828
import tensorflow from '../shared/tensorflowlib'
29+
import Plot from "../plotting/plotly";
2930

3031
const utils = new Utils();
3132

@@ -1358,4 +1359,16 @@ export default class Series extends NDframe implements SeriesInterface {
13581359
}): DataFrame {
13591360
return dummyEncode(this, options)
13601361
}
1362+
1363+
1364+
/**
1365+
* Make plots of Series or DataFrame.
1366+
* Uses the Plotly as backend, so supports Plotly's configuration parameters
1367+
* @param divId Name of the div to show the plot
1368+
* @returns Plotly class that expoese different plot type
1369+
*/
1370+
plot(divId: string) {
1371+
const plt = new Plot(this, divId);
1372+
return plt;
1373+
}
13611374
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/**
2+
* @license
3+
* Copyright 2021, JsData. All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
* ==========================================================================
14+
*/
15+
import Series from "../core/series";
16+
import DataFrame from "../core/frame";
17+
import Utils from "../shared/utils"
18+
import Plotly, { Config, Data, Layout } from "plotly.js-dist-min"
19+
20+
const utils = new Utils();
21+
22+
type PlotConfigObject = {
23+
config?: Partial<Config>;
24+
layout?: Partial<Layout>;
25+
}
26+
27+
try {
28+
// @ts-ignore
29+
const version = Plotly.version;
30+
console.info(`Using Plotly version ${version}`);
31+
} catch (error) {
32+
console.info(`Plotly CDN not found. If you need to make Plots, then add the Plotly CDN to your script`);
33+
}
34+
35+
36+
export default class Plot {
37+
divId: string;
38+
ndframe: DataFrame | Series;
39+
40+
constructor(ndframe: DataFrame | Series, divId: string) {
41+
this.ndframe = ndframe;
42+
this.divId = divId;
43+
}
44+
45+
/**
46+
* Plot Series or DataFrame as lines.
47+
* Uses the Plotly as backend, so supoorts Plotly's configuration parameters
48+
* @param config configuration options for making Plots, supports Plotly.js parameters.
49+
*/
50+
line(configSettings: PlotConfigObject = {}) {
51+
const newConfig = this.$getPlotParams(configSettings);
52+
53+
if (this.ndframe instanceof Series) {
54+
const y = this.ndframe.values as any[]
55+
let trace: Data = {
56+
x: this.ndframe.index,
57+
y,
58+
type: 'scatter',
59+
mode: 'lines',
60+
...configSettings.config,
61+
};
62+
63+
//ts-ignore
64+
Plotly.newPlot(this.divId, [trace], newConfig.layout, newConfig.config);
65+
66+
// } else {
67+
// //check if plotting two columns against each other
68+
// if (utils.keyInObject(newConfig, 'x') && utils.keyInObject(newConfig, 'y')) {
69+
// if (!this.ndframe.columns.includes(newConfig['x'])) {
70+
// throw Error(`Column Error: ${newConfig['x']} not found in columns`);
71+
// }
72+
// if (!this.ndframe.columns.includes(newConfig['y'])) {
73+
// throw Error(`Column Error: ${newConfig['y']} not found in columns`);
74+
// }
75+
76+
77+
// let x = this.ndframe[newConfig['x']].values;
78+
// let y = this.ndframe[newConfig['y']].values;
79+
80+
// let trace = {};
81+
// trace["x"] = x;
82+
// trace['y'] = y;
83+
84+
85+
// let xaxis = {}; let yaxis = {};
86+
// xaxis['title'] = newConfig['x'];
87+
// yaxis['title'] = newConfig['y'];
88+
89+
// newConfig['layout']['xaxis'] = xaxis;
90+
// newConfig['layout']['yaxis'] = yaxis;
91+
92+
// Plotly.newPlot(this.divId, [trace], newConfig['layout'], newConfig);
93+
94+
// } else if (utils.keyInObject(newConfig, 'x') || utils.keyInObject(newConfig, 'y')) {
95+
// //plot single column specified in either of param [x | y] against index
96+
// //plot columns against index
97+
// let data = [];
98+
// let cols_to_plot;
99+
100+
// if (utils.keyInObject(newConfig, "columns")) {
101+
// cols_to_plot = this.$checkIfColsExist(newConfig['columns']);
102+
// } else {
103+
// cols_to_plot = this.ndframe.columns;
104+
// }
105+
106+
// cols_to_plot.forEach((c_name) => {
107+
// let trace = {};
108+
109+
// params.forEach((param) => { //TODO accept indivIdidual configuration for traces
110+
// trace[param] = config[param];
111+
// });
112+
// if (utils.keyInObject(newConfig, 'x')) {
113+
// trace["x"] = this.ndframe[newConfig['x']].values;
114+
// trace["y"] = this.ndframe[c_name].values;
115+
// trace['name'] = c_name;
116+
// } else {
117+
// trace["y"] = this.ndframe[newConfig['y']].values;
118+
// trace["x"] = this.ndframe[c_name].values;
119+
// trace['name'] = c_name;
120+
// }
121+
122+
// data.push(trace);
123+
124+
// });
125+
// Plotly.newPlot(this.divId, data, newConfig['layout'], newConfig);
126+
127+
// } else {
128+
// //plot columns against index
129+
// let data = [];
130+
// let cols_to_plot;
131+
132+
// if (utils.keyInObject(newConfig, "columns")) {
133+
// cols_to_plot = this.$checkIfColsExist(newConfig['columns']);
134+
// } else {
135+
// cols_to_plot = this.ndframe.columns;
136+
// }
137+
138+
// cols_to_plot.forEach((c_name) => {
139+
// let trace = {};
140+
141+
// params.forEach((param) => { //TODO accept indivIdidual configuration for traces
142+
// trace[param] = config[param];
143+
// });
144+
// trace["x"] = this.ndframe.index;
145+
// trace["y"] = this.ndframe[c_name].values;
146+
// trace['name'] = c_name;
147+
148+
// data.push(trace);
149+
150+
// });
151+
// Plotly.newPlot(this.divId, data, newConfig['layout'], newConfig);
152+
153+
// }
154+
155+
}
156+
157+
158+
}
159+
160+
161+
private $getPlotParams(config: PlotConfigObject) {
162+
const newConfig: PlotConfigObject = {
163+
config: config.config || {},
164+
layout: config['layout'] ? config['layout'] : {}
165+
};
166+
return newConfig
167+
}
168+
169+
private $checkIfColsExist(cols: string[]) {
170+
cols.forEach((col) => {
171+
if (!this.ndframe.columns.includes(col)) {
172+
throw Error(`Column Error: ${col} not found in columns. Columns should be one of [ ${this.ndframe.columns} ]`);
173+
}
174+
});
175+
return cols;
176+
}
177+
178+
179+
}

src/danfojs-base/shared/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ export interface SeriesInterface extends NDframeInterface {
152152
cumMax(options?: { inplace?: boolean }): Series | void
153153
cumProd(options?: { inplace?: boolean }): Series | void
154154
lt(other: Series | number | Array<number> | boolean[]): Series
155-
gt(other: Series | number | Array<number>| boolean[]): Series
156-
le(other: Series | number | Array<number>| boolean[]): Series
157-
ge(other: Series | number | Array<number>| boolean[]): Series
158-
ne(other: Series | number | Array<number>| boolean[]): Series
159-
eq(other: Series | number | Array<number>| boolean[]): Series
155+
gt(other: Series | number | Array<number> | boolean[]): Series
156+
le(other: Series | number | Array<number> | boolean[]): Series
157+
ge(other: Series | number | Array<number> | boolean[]): Series
158+
ne(other: Series | number | Array<number> | boolean[]): Series
159+
eq(other: Series | number | Array<number> | boolean[]): Series
160160
replace(oldValue: string | number | boolean, newValue: string | number | boolean, options?: { inplace?: boolean }): Series | void
161161
dropNa(options?: { inplace?: boolean }): Series | void
162162
argSort(): Series

0 commit comments

Comments
 (0)