Skip to content

Commit 0fa8db7

Browse files
committed
add table plot
1 parent c50e83b commit 0fa8db7

3 files changed

Lines changed: 191 additions & 29 deletions

File tree

danfojs/src/core/generic.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ export default class NDframe {
129129
this.columns = this.kwargs['columns']
130130
}
131131

132+
if (utils.__key_in_object(this.kwargs, 'dtypes')) {
133+
this.__set_col_types(this.kwargs['dtypes'], false)
134+
} else {
135+
//infer dtypes
136+
this.__set_col_types(null, true)
137+
}
138+
132139
} else {
133140
//2D or more array
134141
if (!utils.__key_in_object(this.kwargs, 'columns')) {
@@ -158,28 +165,35 @@ export default class NDframe {
158165
__set_col_types(dtypes, infer) {
159166
//set data type for each column in an NDFrame
160167
const __supported_dtypes = ['float32', "int32", 'string', 'boolean']
168+
161169

162170
if (infer) {
163-
//saves array data in column form for easy access
164171
if (this.series) {
165172
this.col_types = utils.__get_t(this.values)
173+
this.col_data = [this.values]
174+
this.col_data_tensor = tf.tensor(this.col_data)
166175
} else {
167-
this.col_data = utils.__get_col_values(this.data)
176+
this.col_data = utils.__get_col_values(this.data) //saves array data in column form for easy access
168177
this.col_data_tensor = tf.tensor(this.col_data) //column wise data saved as tensors used in DataFrame
169178
this.col_types = utils.__get_t(this.col_data)
170179
}
171180
} else {
181+
172182
if (this.series) {
173183
this.col_types = dtypes
184+
this.col_data = [this.values]
185+
this.col_data_tensor = tf.tensor(this.col_data)
186+
174187
} else {
188+
this.col_data = utils.__get_col_values(this.data) //saves array data in column form for easy access
189+
this.col_data_tensor = tf.tensor(this.col_data) //column wise data saved as tensors used in DataFrame
190+
175191
if (Array.isArray(dtypes) && dtypes.length == this.columns.length) {
176192
dtypes.map((type, indx) => {
177193
if (!__supported_dtypes.includes(type)) {
178194
throw new Error(`dtype error: dtype specified at index ${indx} is not supported`)
179195
}
180196
})
181-
this.col_data = utils.__get_col_values(this.data)
182-
this.col_data_tensor = tf.tensor(this.col_data) //column wise data saved as tensors used in DataFrame
183197
this.col_types = dtypes
184198
} else {
185199
throw new Error(`dtypes: lenght mismatch. Specified dtype has a lenght

danfojs/src/core/utils.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ export class Utils {
153153
__get_row_values(data) {
154154
let col_names = Object.keys(data)
155155
let col_data = Object.values(data)
156+
//check lengths to ensure they are equal
157+
let first_col_len = col_data[0].length
158+
col_data.forEach(data=>{
159+
if (data.length != first_col_len){
160+
throw Error("Length Error: Length of columns must be the same!")
161+
}
162+
})
156163
let rows_len = col_data[0].length
157164
let cols_len = col_names.length
158165
var rows_arr = []

danfojs/src/plotting/plot.js

Lines changed: 166 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -92,31 +92,6 @@ export class Plot {
9292

9393
newPlot(this.div, data, this_config['layout'])
9494

95-
} else if (this_config['type'] == 'table') {
96-
let header = {}
97-
let cells = {}
98-
99-
header['values'] = this.ndframe.column_names
100-
cells['values'] = this.ndframe.col_data
101-
102-
if (this_config['header_style']) {
103-
Object.keys(this_config['header_style']).forEach(param => {
104-
header[param] = this_config['header_style'][param]
105-
})
106-
}
107-
108-
if (this_config['cell_style']) {
109-
Object.keys(this_config['cell_style']).forEach(param => {
110-
header[param] = this_config['cell_style'][param]
111-
})
112-
}
113-
var data = [{
114-
type: 'table',
115-
header: header,
116-
cells: cells
117-
}]
118-
newPlot(this.div, data, this_config['layout']);
119-
12095
} else if (this_config['type'] == 'box') {
12196
let cols_2_show = []
12297
let data = []
@@ -800,6 +775,172 @@ export class Plot {
800775
}
801776

802777

778+
779+
/**
780+
* Plot Violin plots from Series or DataFrame as lines.
781+
* Uses the Plotly as backend, so supoorts Plotly's configuration parameters
782+
* @param {Object} config configuration options for making Plots, supports Plotly parameters
783+
*/
784+
violin(config = {}) {
785+
786+
let ret_params = this.__get_plot_params(config)
787+
let this_config = ret_params[0]
788+
let params = ret_params[1]
789+
790+
if (this.ndframe instanceof Series) {
791+
let trace = {}
792+
let y = this.ndframe.values
793+
794+
params.forEach(param => {
795+
if (!param == "layout") {
796+
trace[param] = config[param]
797+
}
798+
})
799+
800+
trace["y"] = y
801+
trace['type'] = "violin"
802+
803+
newPlot(this.div, [trace], this_config['layout']);
804+
805+
} else {
806+
//check if plotting two columns against each other
807+
if (utils.__key_in_object(this_config, 'x') && utils.__key_in_object(this_config, 'y')) {
808+
if (!this.ndframe.column_names.includes(this_config['x'])) {
809+
throw Error(`Column Error: ${this_config['x']} not found in columns`)
810+
}
811+
if (!this.ndframe.column_names.includes(this_config['y'])) {
812+
throw Error(`Column Error: ${this_config['y']} not found in columns`)
813+
}
814+
815+
816+
let x = this.ndframe[this_config['x']].values
817+
let y = this.ndframe[this_config['y']].values
818+
819+
let trace = {}
820+
trace["x"] = x
821+
trace['y'] = y
822+
trace['type'] = 'violin'
823+
824+
825+
let xaxis = {}; let yaxis = {}
826+
xaxis['title'] = this_config['x']
827+
yaxis['title'] = this_config['y']
828+
829+
this_config['layout']['xaxis'] = xaxis
830+
this_config['layout']['yaxis'] = yaxis
831+
832+
newPlot(this.div, [trace], this_config['layout']);
833+
834+
} else if (utils.__key_in_object(this_config, 'x') || utils.__key_in_object(this_config, 'y')) {
835+
//plot single column specified in either of param [x | y] against index
836+
let trace = {}
837+
838+
params.forEach(param => {
839+
if (!param == "layout") {
840+
trace[param] = config[param]
841+
}
842+
})
843+
844+
if (utils.__key_in_object(this_config, 'x')) {
845+
trace['x'] = this.ndframe[this_config['x']].values
846+
trace['y'] = this.ndframe.index
847+
trace['type'] = 'violin'
848+
} else {
849+
trace['x'] = this.ndframe.index
850+
trace['y'] = this_config['y']
851+
trace['type'] = 'violin'
852+
}
853+
854+
newPlot(this.div, [trace], this_config['layout']);
855+
856+
} else {
857+
//plot columns against index
858+
let data = []
859+
let cols_to_plot;
860+
861+
if (utils.__key_in_object(this_config, "columns")) {
862+
cols_to_plot = this.____check_if_cols_exist(this_config['columns'])
863+
} else {
864+
cols_to_plot = this.ndframe.column_names
865+
}
866+
867+
cols_to_plot.forEach(c_name => {
868+
let trace = {}
869+
870+
params.forEach(param => { //TODO accept individual configuration for traces
871+
trace[param] = config[param]
872+
})
873+
trace["y"] = this.ndframe[c_name].values
874+
trace['name'] = c_name
875+
trace['type'] = 'violin'
876+
data.push(trace)
877+
878+
})
879+
newPlot(this.div, data, this_config['layout']);
880+
881+
}
882+
883+
}
884+
885+
886+
}
887+
888+
/**
889+
* Display DataFrame in a div using D3.js format
890+
* Uses the Plotly as backend, so supoorts Plotly's configuration parameters
891+
* @param {Object} config configuration options for making Plots, supports Plotly parameters
892+
*/
893+
table(config = {}) {
894+
let ret_params = this.__get_plot_params(config)
895+
let this_config = ret_params[0]
896+
let header = {}
897+
let cells = {}
898+
let cols_data = []
899+
let cols_2_show;
900+
901+
902+
if (utils.__key_in_object(this_config, 'columns')) {
903+
904+
this_config['columns'].forEach(cname => {
905+
if (!this.ndframe.column_names.includes(cname)) {
906+
throw Error(`Column Error: ${cname} not found in columns. Columns should be one of [ ${this.ndframe.column_names} ]`)
907+
}
908+
909+
let idx = this.ndframe.column_names.indexOf(cname)
910+
cols_data.push(this.ndframe.col_data[idx])
911+
})
912+
cols_2_show = this_config['columns']
913+
} else {
914+
915+
cols_2_show = this.ndframe.column_names
916+
cols_data = this.ndframe.col_data
917+
918+
}
919+
920+
header['values'] = cols_2_show
921+
cells['values'] = cols_data
922+
923+
if (this_config['header_style']) {
924+
Object.keys(this_config['header_style']).forEach(param => {
925+
header[param] = this_config['header_style'][param]
926+
})
927+
}
928+
929+
if (this_config['cell_style']) {
930+
Object.keys(this_config['cell_style']).forEach(param => {
931+
header[param] = this_config['cell_style'][param]
932+
})
933+
}
934+
var data = [{
935+
type: 'table',
936+
header: header,
937+
cells: cells
938+
}]
939+
newPlot(this.div, data, this_config['layout']);
940+
941+
}
942+
943+
803944
__get_plot_params(config) {
804945
let params = Object.keys(config)
805946
let this_config = {}

0 commit comments

Comments
 (0)