From c72dce1107a324f32cd0f06001ea3c0b696159cf Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Fri, 13 Oct 2023 02:44:52 -0300 Subject: [PATCH 01/11] WIP: --- plot/scripts/create-venv.sh | 25 ---------- plot/scripts/plotter.py | 91 ----------------------------------- plot/scripts/python.sh | 21 --------- plot/scripts/run.sh | 24 ---------- plot/show.v | 94 +++++++++++++++---------------------- 5 files changed, 39 insertions(+), 216 deletions(-) delete mode 100755 plot/scripts/create-venv.sh delete mode 100644 plot/scripts/plotter.py delete mode 100644 plot/scripts/python.sh delete mode 100755 plot/scripts/run.sh diff --git a/plot/scripts/create-venv.sh b/plot/scripts/create-venv.sh deleted file mode 100755 index a35252a17..000000000 --- a/plot/scripts/create-venv.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -ROOT=$(dirname "$0") - -usage() { - echo "Usage: ${0} " - exit 1 -} - -VENV="${1}" - -if [ -z "${VENV}" ]; then - usage -fi - -source "${ROOT}/python.sh" || exit - -if [ -d "${VENV}" ]; then - exit 0 -fi - -"${python_bin}" -m venv "${VENV}" -source "${VENV}/bin/activate" -"${python_bin}" -m pip install cython plotly -deactivate diff --git a/plot/scripts/plotter.py b/plot/scripts/plotter.py deleted file mode 100644 index 4a0581eb1..000000000 --- a/plot/scripts/plotter.py +++ /dev/null @@ -1,91 +0,0 @@ -import argparse -import os -import json -import plotly.graph_objects as go - - -def is_valid_file(parser, arg): - """ - Check if the provided file path exists. - """ - if not os.path.exists(arg): - parser.error("The file %s does not exist!" % arg) - else: - return open(arg, "r") # return an open file handle - - -def load_json_file(file_handle): - """ - Load and return JSON data from a file handle. - """ - return json.load(file_handle) - - -def map_trace_type_to_plotly_object(trace_type): - """ - Map vsl.plot.TraceType enum to Plotly objects. - """ - type_map = { - 'scatter': go.Scatter, - 'pie': go.Pie, - 'heatmap': go.Heatmap, - 'surface': go.Surface, - 'scatter3d': go.Scatter3d, - 'bar': go.Bar, - 'histogram': go.Histogram - } - return type_map[trace_type] - - -def process_trace(trace): - """ - Process a trace to ensure only accepted keys are present. - """ - trace_type = trace.pop("trace_type") - - # Remove all JSON keys not accepted by Plotly. - accepted = dir(map_trace_type_to_plotly_object(trace_type)) - keys = list(trace.keys()) - for k in keys: - if k not in accepted: - trace.pop(k) - - return map_trace_type_to_plotly_object(trace_type)(trace) - - -def main(): - parser = argparse.ArgumentParser(description="Run training") - parser.add_argument( - "--data", - dest="data", - required=True, - help="input file with data", - metavar="FILE", - type=lambda x: is_valid_file(parser, x), - ) - parser.add_argument( - "--layout", - dest="layout", - required=True, - help="input file with layout", - metavar="FILE", - type=lambda x: is_valid_file(parser, x), - ) - - args = parser.parse_args() - - # Read data JSON file. - data = load_json_file(args.data) - - # Read layout JSON file. - layout = load_json_file(args.layout) - - # List of traces to be plotted. - plot_data = [process_trace(trace) for trace in data] - - fig = go.Figure(data=plot_data, layout=go.Layout(layout)) - fig.show() - - -if __name__ == "__main__": - main() diff --git a/plot/scripts/python.sh b/plot/scripts/python.sh deleted file mode 100644 index 0d50d42a5..000000000 --- a/plot/scripts/python.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -python_bin="python" - -if type -p python3 &>/dev/null; then - python_bin="python3" -fi - -if ! type -p "${python_bin}" &>/dev/null; then - echo "Install Python 3 and link it to python or python3 binary." - exit 1 -fi - -pyver=$("${python_bin}" -c "import platform; print(str(platform.python_version()).split('.')[0])") - -if [[ "${pyver}" != "3" ]]; then - echo "The detected Python version is < 3.0.0, -please update your Python version to 3+. If you already have - Python 3+ under '${python_bin}', please link '${python_bin}' to python binary." - exit 1 -fi diff --git a/plot/scripts/run.sh b/plot/scripts/run.sh deleted file mode 100755 index ded99e064..000000000 --- a/plot/scripts/run.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -ROOT=$(dirname "$0") - -usage() { - echo "Usage: ${0} " - exit 1 -} - -VENV="${1}" -DATA="${2}" -LAYOUT="${3}" - -if [ -z "${VENV}" ] || [ -z "${DATA}" ] || [ -z "${LAYOUT}" ]; then - usage -fi - -source "${ROOT}/python.sh" || exit - -"${ROOT}"/create-venv.sh "${VENV}" || exit - -source "${VENV}/bin/activate" -"${python_bin}" "${ROOT}/plotter.py" --data "${DATA}" --layout "${LAYOUT}" -deactivate diff --git a/plot/show.v b/plot/show.v index f8a00680d..71a2eb522 100644 --- a/plot/show.v +++ b/plot/show.v @@ -1,70 +1,54 @@ module plot import json -import os import time -import vsl.errors +import vweb + +const port = 8082 const ( schema_version = 'v1.0.3' - venv_dir_name = '.plotvenv_${schema_version}' data_dir_name = '.data_${schema_version}' ) -pub fn (p Plot) show() ! { - create_venv()! - - ts := time.now().format_ss_micro() - plot_str := json.encode_pretty(p.traces) - - venv_path := solve_mod_path(plot.venv_dir_name) - if !os.is_dir(venv_path) { - return errors.error('plotly virtualenv not found', .efailed) - } - - data_dir_path := solve_mod_path(plot.data_dir_name) - if !os.is_dir(data_dir_path) { - os.mkdir(data_dir_path) or { - return errors.error('could not create needed dir path at ${data_dir_path}.', - .efailed) - } - } - - data_path := solve_mod_path(plot.data_dir_name, 'data-${ts}.json') - layout_path := solve_mod_path(plot.data_dir_name, 'layout-${ts}.json') - run_path := solve_mod_path('scripts', 'run.sh') - - os.write_file(data_path, plot_str) or { - return errors.error('could not save the plot to a JSON file at ${data_path}.', - .efailed) - } - layout_str := json.encode(p.layout) - os.write_file(layout_path, layout_str) or { - return errors.error('could not save the layout to a JSON file at ${layout_path}.', - .efailed) - } - $if !test ? { - result := os.execute('bash ${run_path} "${venv_path}" "${data_path}" "${layout_path}"') - if result.exit_code != 0 { - return error_with_code(result.output, result.exit_code) - } - println(result.output) - } +struct App { + vweb.Context + plot Plot [vweb_global] } -// create_venv will ensure that all dependencies are correctly installed and venv initiallized -fn create_venv() ! { - venv_path := solve_mod_path(plot.venv_dir_name) - if !os.is_dir(venv_path) { - println('Creating plotly virtualenv...') - } - init_path := solve_mod_path('scripts', 'create-venv.sh') - result := os.execute('bash ${init_path} "${venv_path}"') - if result.exit_code != 0 { - return errors.error(result.output, .efailed) - } +pub fn (mut app App) index() vweb.Result { + // For some reason this is not working yet + data := json.encode_pretty(app.plot.traces) + layout := json.encode_pretty(app.plot.layout) + spawn fn () { + time.sleep(100 * time.millisecond) + exit(0) + }() + return app.html(' + + + VSL Plot + + +
+ + + +') } -fn solve_mod_path(dirs ...string) string { - return os.join_path(@VMODROOT, ...dirs) +pub fn (p Plot) show() ! { + $if !test ? { + vweb.run(&App{ + plot: p + }, plot.port) + } } From b92c2fa16ebe96a07986b24bd9149992e241a37f Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Fri, 13 Oct 2023 02:48:55 -0300 Subject: [PATCH 02/11] WIP: --- plot/show.v | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plot/show.v b/plot/show.v index 71a2eb522..1bd5e3c0a 100644 --- a/plot/show.v +++ b/plot/show.v @@ -6,11 +6,6 @@ import vweb const port = 8082 -const ( - schema_version = 'v1.0.3' - data_dir_name = '.data_${schema_version}' -) - struct App { vweb.Context plot Plot [vweb_global] From 721d662f3d0db7cc20bf5f2d13eba8183d80aa82 Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 18:26:24 -0300 Subject: [PATCH 03/11] Updated default port --- plot/show.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plot/show.v b/plot/show.v index 1bd5e3c0a..d9adab93b 100644 --- a/plot/show.v +++ b/plot/show.v @@ -4,7 +4,8 @@ import json import time import vweb -const port = 8082 +// port is the port to run the server on. If 0, it will run on the next available port. +const port = 0 struct App { vweb.Context From 45ebb81bdcd42160b59750e2465c7913eaf72683 Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 21:09:31 -0300 Subject: [PATCH 04/11] Updated plotly usage --- examples/data_analysis_example/main.v | 23 ++- examples/fft_plot_example/main.v | 8 +- examples/plot_annotated_pie_chart/main.v | 5 +- examples/plot_bar/main.v | 5 +- examples/plot_basic_heatmap/main.v | 5 +- examples/plot_bubble_chart/main.v | 5 +- examples/plot_grouped_bar_chart/main.v | 8 +- examples/plot_heatmap_golden_ratio/main.v | 5 +- examples/plot_histogram/main.v | 5 +- examples/plot_line_plot_with_areas/main.v | 8 +- examples/plot_pie/main.v | 29 ++-- examples/plot_ripple_surface/main.v | 5 +- examples/plot_saddle_surface/main.v | 5 +- examples/plot_scatter/main.v | 5 +- examples/plot_scatter3d_1/main.v | 5 +- examples/plot_scatter3d_2/main.v | 5 +- examples/plot_scatter3d_easing/main.v | 5 +- examples/plot_scatter_colorscale/main.v | 5 +- examples/plot_scatter_easing/main.v | 5 +- examples/plot_scatter_with_bars/main.v | 8 +- examples/plot_scatter_with_histogram/main.v | 8 +- examples/plot_scatter_with_regression/main.v | 8 +- examples/plot_shaded_area_sin/main.v | 8 +- examples/plot_sin_cos_surface/main.v | 5 +- examples/plot_surface/main.v | 5 +- examples/plot_surface_easing/main.v | 5 +- examples/roots_bisection_solver/main.v | 8 +- ml/kmeans.v | 8 +- ml/knn.v | 5 +- ml/linreg.v | 8 +- plot/plot.v | 44 +++++- plot/plot_test.v | 5 +- plot/show.v | 68 ++++++--- plot/trace.v | 147 +++++++++++++++---- 34 files changed, 296 insertions(+), 190 deletions(-) diff --git a/examples/data_analysis_example/main.v b/examples/data_analysis_example/main.v index ea581a5f8..6d6a3a530 100644 --- a/examples/data_analysis_example/main.v +++ b/examples/data_analysis_example/main.v @@ -75,7 +75,7 @@ fn main() { mut x2_class1 := []f64{} for i in 0 .. data.nb_samples { - if y[i] == 0 { + if y[i] == 0.0 { x1_class0 << x1[i] x2_class0 << x2[i] } else { @@ -85,11 +85,10 @@ fn main() { } // Add traces for each class in the 3D plot - plt_3d.add_trace( - trace_type: .scatter3d + plt_3d.scatter3d( x: x1_class0 y: x2_class0 - z: []f64{len: x1_class0.len, init: 0.0} + z: [][]f64{len: x1_class0.len, init: [0.0]} mode: 'markers' marker: plot.Marker{ size: []f64{len: x1_class0.len, init: 8.0} @@ -97,12 +96,10 @@ fn main() { } name: 'Class 0' ) - - plt_3d.add_trace( - trace_type: .scatter3d + plt_3d.scatter3d( x: x1_class1 y: x2_class1 - z: []f64{len: x1_class1.len, init: 0.0} + z: [][]f64{len: x1_class1.len, init: [0.0]} mode: 'markers' marker: plot.Marker{ size: []f64{len: x1_class1.len, init: 8.0} @@ -112,7 +109,7 @@ fn main() { ) // Configure the layout of the 3D plot - plt_3d.set_layout( + plt_3d.layout( title: 'Two-class Data' xaxis: plot.Axis{ title: plot.AxisTitle{ @@ -136,22 +133,20 @@ fn main() { // Visualize statistics in a bar chart mut plt_bars := plot.new_plot() - plt_bars.add_trace( - trace_type: .bar + plt_bars.bar( x: []string{len: stat.mean_x.len, init: 'Class ${index}'} y: stat.mean_x name: 'Mean' ) - plt_bars.add_trace( - trace_type: .bar + plt_bars.bar( x: []string{len: stat.sig_x.len, init: 'Class ${index}'} y: stat.sig_x name: 'Standard Deviation' ) // Configure the layout of the bar chart - plt_bars.set_layout( + plt_bars.layout( title: 'Feature Statistics' ) diff --git a/examples/fft_plot_example/main.v b/examples/fft_plot_example/main.v index 9adc13d0e..4059fb8dc 100644 --- a/examples/fft_plot_example/main.v +++ b/examples/fft_plot_example/main.v @@ -25,8 +25,7 @@ fn main() { mut plt := plot.new_plot() // Add a scatter plot for the original signal - plt.add_trace( - trace_type: .scatter + plt.scatter( x: []f64{len: original_signal.len, init: f64(index)} y: original_signal mode: 'markers' @@ -37,8 +36,7 @@ fn main() { ) // Add a scatter plot for the imaginary part of the spectrum - plt.add_trace( - trace_type: .scatter + plt.scatter( x: []f64{len: spectrum.len, init: f64(index)} y: spectrum mode: 'markers' @@ -49,7 +47,7 @@ fn main() { ) // Set up the layout - plt.set_layout( + plt.layout( title: 'Signal and FFT Spectrum' ) diff --git a/examples/plot_annotated_pie_chart/main.v b/examples/plot_annotated_pie_chart/main.v index 572f34024..f9a83aa67 100644 --- a/examples/plot_annotated_pie_chart/main.v +++ b/examples/plot_annotated_pie_chart/main.v @@ -7,13 +7,12 @@ fn main() { values := [25.0, 30, 15, 30] mut plt := plot.new_plot() - plt.add_trace( - trace_type: .pie + plt.pie( labels: labels values: values textinfo: 'percent+label' ) - plt.set_layout( + plt.layout( title: 'Pie Chart with Annotations' ) plt.show()! diff --git a/examples/plot_bar/main.v b/examples/plot_bar/main.v index e2972f32e..2cf02e1e1 100644 --- a/examples/plot_bar/main.v +++ b/examples/plot_bar/main.v @@ -5,12 +5,11 @@ import vsl.plot fn main() { mut plt := plot.new_plot() - plt.add_trace( - trace_type: .bar + plt.bar( x: ['China', 'India', 'USA', 'Indonesia', 'Pakistan'] y: [1411778724.0, 1379217184, 331989449, 271350000, 225200000] ) - plt.set_layout( + plt.layout( title: 'Countries by population' ) plt.show()! diff --git a/examples/plot_basic_heatmap/main.v b/examples/plot_basic_heatmap/main.v index aa7a95333..7beaf676b 100644 --- a/examples/plot_basic_heatmap/main.v +++ b/examples/plot_basic_heatmap/main.v @@ -8,13 +8,12 @@ y := ['Morning', 'Afternoon', 'Evening'] mut plt := plot.new_plot() -plt.add_trace( - trace_type: .heatmap +plt.heatmap( x: x y: y z: z ) -plt.set_layout( +plt.layout( title: 'Heatmap Basic Implementation' width: 750 height: 750 diff --git a/examples/plot_bubble_chart/main.v b/examples/plot_bubble_chart/main.v index 684258ac3..8294ec9cc 100644 --- a/examples/plot_bubble_chart/main.v +++ b/examples/plot_bubble_chart/main.v @@ -8,8 +8,7 @@ fn main() { size := []f64{len: 10, init: f64(index) * 10.0} mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y mode: 'markers' @@ -19,7 +18,7 @@ fn main() { } name: 'Bubble Chart' ) - plt.set_layout( + plt.layout( title: 'Bubble Chart' ) plt.show()! diff --git a/examples/plot_grouped_bar_chart/main.v b/examples/plot_grouped_bar_chart/main.v index f16b8f21a..1c2447f4d 100644 --- a/examples/plot_grouped_bar_chart/main.v +++ b/examples/plot_grouped_bar_chart/main.v @@ -8,19 +8,17 @@ fn main() { values2 := [8.0, 14, 5, 10] mut plt := plot.new_plot() - plt.add_trace( - trace_type: .bar + plt.bar( x: categories y: values1 name: 'Group 1' ) - plt.add_trace( - trace_type: .bar + plt.bar( x: categories y: values2 name: 'Group 2' ) - plt.set_layout( + plt.layout( title: 'Grouped Bar Chart' ) plt.show()! diff --git a/examples/plot_heatmap_golden_ratio/main.v b/examples/plot_heatmap_golden_ratio/main.v index 5d9c67a0a..f7e8da879 100644 --- a/examples/plot_heatmap_golden_ratio/main.v +++ b/examples/plot_heatmap_golden_ratio/main.v @@ -26,13 +26,12 @@ z := [[13.0, 3, 3, 5], [13.0, 2, 1, 5], [13.0, 10, 11, 12], [13.0, 8, 8, 8]] mut plt := plot.new_plot() -plt.add_trace( - trace_type: .heatmap +plt.heatmap( x: xe y: ye z: z ) -plt.set_layout( +plt.layout( title: 'Heatmap with Unequal Block Sizes' width: 750 height: 750 diff --git a/examples/plot_histogram/main.v b/examples/plot_histogram/main.v index 54f0dfce1..1aa4c0105 100644 --- a/examples/plot_histogram/main.v +++ b/examples/plot_histogram/main.v @@ -10,8 +10,7 @@ for _ in 1 .. 1000 { x1 << rand.f64n(100) or { 0 } } mut plt := plot.new_plot() -plt.add_trace( - trace_type: .histogram +plt.histogram( x: x1 xbins: { 'start': f32(0) @@ -19,7 +18,7 @@ plt.add_trace( 'size': 2 } ) -plt.set_layout( +plt.layout( title: 'Histogram Example' width: 750 height: 750 diff --git a/examples/plot_line_plot_with_areas/main.v b/examples/plot_line_plot_with_areas/main.v index 3a8ec1d0e..66ac1e562 100644 --- a/examples/plot_line_plot_with_areas/main.v +++ b/examples/plot_line_plot_with_areas/main.v @@ -9,8 +9,7 @@ fn main() { y2 := x.map(math.cos(it)) mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y1 mode: 'lines' @@ -19,8 +18,7 @@ fn main() { } name: 'sin(x)' ) - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y2 mode: 'lines' @@ -29,7 +27,7 @@ fn main() { } name: 'cos(x)' ) - plt.set_layout( + plt.layout( title: 'Line Plot with Highlighted Areas' ) plt.show()! diff --git a/examples/plot_pie/main.v b/examples/plot_pie/main.v index 9dcb8cdee..e896db4ff 100644 --- a/examples/plot_pie/main.v +++ b/examples/plot_pie/main.v @@ -2,18 +2,19 @@ module main import vsl.plot -mut plt := plot.new_plot() +fn main() { + mut plt := plot.new_plot() -plt.add_trace( - trace_type: .pie - labels: ['Nitrogen', 'Oxygen', 'Argon', 'Other'] - values: [78.0, 21, 0.9, 0.1] - pull: [0.0, 0.1, 0, 0] - hole: 0.25 -) -plt.set_layout( - title: 'Gases in the atmosphere' - width: 750 - height: 750 -) -plt.show()! + plt.pie( + labels: ['Nitrogen', 'Oxygen', 'Argon', 'Other'] + values: [78.0, 21, 0.9, 0.1] + pull: [0.0, 0.1, 0, 0] + hole: 0.25 + ) + plt.layout( + title: 'Gases in the atmosphere' + width: 750 + height: 750 + ) + plt.show()! +} diff --git a/examples/plot_ripple_surface/main.v b/examples/plot_ripple_surface/main.v index 6319617a1..15baf79e2 100644 --- a/examples/plot_ripple_surface/main.v +++ b/examples/plot_ripple_surface/main.v @@ -19,14 +19,13 @@ fn main() { } mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + plt.surface( x: x y: y z: z colorscale: 'Viridis' ) - plt.set_layout( + plt.layout( title: 'Ripple Effect Surface' ) plt.show()! diff --git a/examples/plot_saddle_surface/main.v b/examples/plot_saddle_surface/main.v index 260b2cfd2..8df68b528 100644 --- a/examples/plot_saddle_surface/main.v +++ b/examples/plot_saddle_surface/main.v @@ -18,14 +18,13 @@ fn main() { } mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + plt.surface( x: x y: y z: z colorscale: 'Viridis' ) - plt.set_layout( + plt.layout( title: 'Saddle Surface' ) plt.show()! diff --git a/examples/plot_scatter/main.v b/examples/plot_scatter/main.v index 97525ee58..31e459c38 100644 --- a/examples/plot_scatter/main.v +++ b/examples/plot_scatter/main.v @@ -21,8 +21,7 @@ y := [ x := util.arange(y.len).map(f64(it)) mut plt := plot.new_plot() -plt.add_trace( - trace_type: .scatter +plt.scatter( x: x y: y mode: 'lines+markers' @@ -34,7 +33,7 @@ plt.add_trace( color: '#FF0000' } ) -plt.set_layout( +plt.layout( title: 'Scatter plot example' ) plt.show()! diff --git a/examples/plot_scatter3d_1/main.v b/examples/plot_scatter3d_1/main.v index 0167efbf9..6749d083a 100644 --- a/examples/plot_scatter3d_1/main.v +++ b/examples/plot_scatter3d_1/main.v @@ -23,8 +23,7 @@ fn main() { z := util.arange(y.len).map(util.arange(y.len).map(f64(it * it))) mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter3d + plt.scatter3d( x: x y: y z: z @@ -37,7 +36,7 @@ fn main() { color: '#0000FF' } ) - plt.set_layout( + plt.layout( title: 'Scatter plot example' ) plt.show()! diff --git a/examples/plot_scatter3d_2/main.v b/examples/plot_scatter3d_2/main.v index b394b3c59..27be00dc6 100644 --- a/examples/plot_scatter3d_2/main.v +++ b/examples/plot_scatter3d_2/main.v @@ -16,8 +16,7 @@ fn main() { } mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter3d + plt.scatter3d( x: x y: y z: z @@ -27,7 +26,7 @@ fn main() { color: []string{len: x.len, init: '#0000FF'} } ) - plt.set_layout( + plt.layout( title: 'Scatter plot example' ) plt.show()! diff --git a/examples/plot_scatter3d_easing/main.v b/examples/plot_scatter3d_easing/main.v index 291838ac7..96c43851e 100644 --- a/examples/plot_scatter3d_easing/main.v +++ b/examples/plot_scatter3d_easing/main.v @@ -16,9 +16,8 @@ fn main() { // Create the Scatter3D plot mut plt := plot.new_plot() - plt.add_trace( + plt.scatter3d( name: 'Easing Scatter3D' - trace_type: .scatter3d x: x_values y: y_values z: [][]f64{len: z_values.len, init: z_values} @@ -30,7 +29,7 @@ fn main() { } ) - plt.set_layout(title: '3D Scatter Plot with Easing') + plt.layout(title: '3D Scatter Plot with Easing') plt.show()! } diff --git a/examples/plot_scatter_colorscale/main.v b/examples/plot_scatter_colorscale/main.v index 0509d93e1..5935b6b9d 100644 --- a/examples/plot_scatter_colorscale/main.v +++ b/examples/plot_scatter_colorscale/main.v @@ -21,8 +21,7 @@ y := [ x := util.arange(y.len).map(f64(it)) mut plt := plot.new_plot() -plt.add_trace( - trace_type: .scatter +plt.scatter( x: x y: y mode: 'lines+markers' @@ -31,7 +30,7 @@ plt.add_trace( size: []f64{len: x.len, init: 10.0} } ) -plt.set_layout( +plt.layout( title: 'Scatter plot example' ) plt.show()! diff --git a/examples/plot_scatter_easing/main.v b/examples/plot_scatter_easing/main.v index 7c8ddbeb6..da454e1c1 100644 --- a/examples/plot_scatter_easing/main.v +++ b/examples/plot_scatter_easing/main.v @@ -15,9 +15,8 @@ fn main() { // Create the Scatter plot mut plt := plot.new_plot() - plt.add_trace( + plt.scatter( name: 'Easing Scatter' - trace_type: .scatter x: x_values y: y_values mode: 'markers' @@ -29,7 +28,7 @@ fn main() { } ) - plt.set_layout(title: 'Scatter Plot with Easing') + plt.layout(title: 'Scatter Plot with Easing') plt.show()! } diff --git a/examples/plot_scatter_with_bars/main.v b/examples/plot_scatter_with_bars/main.v index fe742db9f..ce5c21ca2 100644 --- a/examples/plot_scatter_with_bars/main.v +++ b/examples/plot_scatter_with_bars/main.v @@ -8,8 +8,7 @@ fn main() { y := x.map(it * it) mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y mode: 'markers' @@ -18,15 +17,14 @@ fn main() { color: []string{len: x.len, init: '#FF0000'} } ) - plt.add_trace( - trace_type: .bar + plt.bar( x: x.map(it.str()) y: y marker: plot.Marker{ color: []string{len: x.len, init: '#0000FF'} } ) - plt.set_layout( + plt.layout( title: 'Scatter with Bars' ) plt.show()! diff --git a/examples/plot_scatter_with_histogram/main.v b/examples/plot_scatter_with_histogram/main.v index 994882022..2e83ed99b 100644 --- a/examples/plot_scatter_with_histogram/main.v +++ b/examples/plot_scatter_with_histogram/main.v @@ -12,8 +12,7 @@ fn main() { } mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: x mode: 'markers' @@ -22,11 +21,10 @@ fn main() { color: []string{len: x.len, init: '#FF0000'} } ) - plt.add_trace( - trace_type: .histogram + plt.histogram( x: x ) - plt.set_layout( + plt.layout( title: 'Scatter with Histogram' ) plt.show()! diff --git a/examples/plot_scatter_with_regression/main.v b/examples/plot_scatter_with_regression/main.v index ff99d4fd2..d1a3b4b9b 100644 --- a/examples/plot_scatter_with_regression/main.v +++ b/examples/plot_scatter_with_regression/main.v @@ -7,8 +7,7 @@ fn main() { y := [1.2, 2.1, 3.0, 4.5, 5.8, 7.0, 8.2, 9.1, 10.5, 11.8] mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y mode: 'markers' @@ -18,8 +17,7 @@ fn main() { } name: 'Data Points' ) - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y mode: 'lines' @@ -28,7 +26,7 @@ fn main() { } name: 'Regression Line' ) - plt.set_layout( + plt.layout( title: 'Scatter Plot with Regression Line' ) plt.show()! diff --git a/examples/plot_shaded_area_sin/main.v b/examples/plot_shaded_area_sin/main.v index 2d6812003..b571e028d 100644 --- a/examples/plot_shaded_area_sin/main.v +++ b/examples/plot_shaded_area_sin/main.v @@ -8,8 +8,7 @@ fn main() { y := x.map(math.sin(it)) mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: y mode: 'lines' @@ -18,8 +17,7 @@ fn main() { } name: 'sin(x)' ) - plt.add_trace( - trace_type: .scatter + plt.scatter( x: x y: []f64{len: x.len} mode: 'lines' @@ -30,7 +28,7 @@ fn main() { } name: 'Shaded Area' ) - plt.set_layout( + plt.layout( title: 'Shaded Area under sin(x)' ) plt.show()! diff --git a/examples/plot_sin_cos_surface/main.v b/examples/plot_sin_cos_surface/main.v index fcaa0098a..62a6a2ffd 100644 --- a/examples/plot_sin_cos_surface/main.v +++ b/examples/plot_sin_cos_surface/main.v @@ -18,14 +18,13 @@ fn main() { } mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + plt.surface( x: x y: y z: z colorscale: 'Viridis' ) - plt.set_layout( + plt.layout( title: 'Surface Plot of sin(x) * cos(y)' ) plt.show()! diff --git a/examples/plot_surface/main.v b/examples/plot_surface/main.v index bc52bb28c..bad46f9b3 100644 --- a/examples/plot_surface/main.v +++ b/examples/plot_surface/main.v @@ -18,14 +18,13 @@ fn main() { } mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + plt.surface( x: x y: y z: z colorscale: 'Viridis' ) - plt.set_layout( + plt.layout( title: 'Surface Plot Example' ) plt.show()! diff --git a/examples/plot_surface_easing/main.v b/examples/plot_surface_easing/main.v index 943110eec..069e635ec 100644 --- a/examples/plot_surface_easing/main.v +++ b/examples/plot_surface_easing/main.v @@ -14,15 +14,14 @@ fn main() { // Create the Surface plot mut plt := plot.new_plot() - plt.add_trace( + plt.surface( name: 'Easing Surface' - trace_type: .surface x: x_values y: y_values z: [][]f64{len: z_values.len, init: z_values} colorscale: 'viridis' ) - plt.set_layout(title: 'Surface Plot with Easing') + plt.layout(title: 'Surface Plot with Easing') plt.show()! } diff --git a/examples/roots_bisection_solver/main.v b/examples/roots_bisection_solver/main.v index c6e19559a..e38053632 100644 --- a/examples/roots_bisection_solver/main.v +++ b/examples/roots_bisection_solver/main.v @@ -39,8 +39,7 @@ mut plt := plot.new_plot() x := util.lin_space(0.0, 3.0, 100) y := x.map(f_cos(it, []f64{})) -plt.add_trace( - trace_type: .scatter +plt.scatter( x: x y: y mode: 'lines' @@ -48,8 +47,7 @@ plt.add_trace( color: '#FF0000' } ) -plt.add_trace( - trace_type: .scatter +plt.scatter( x: [result.x] y: [result.fx] mode: 'markers' @@ -57,7 +55,7 @@ plt.add_trace( color: ['#0000FF'] } ) -plt.set_layout( +plt.layout( title: 'cos(x)' ) plt.show()! diff --git a/ml/kmeans.v b/ml/kmeans.v index d0255ee37..941a1951b 100644 --- a/ml/kmeans.v +++ b/ml/kmeans.v @@ -150,7 +150,7 @@ pub fn (o &Kmeans) str() string { // plot method for visualizing the clustering pub fn (o &Kmeans) plot() ! { mut plt := plot.new_plot() - plt.set_layout( + plt.layout( title: 'K-means Clustering' ) @@ -168,9 +168,8 @@ pub fn (o &Kmeans) plot() ! { } } - plt.add_trace( + plt.scatter( name: 'class #${i}' - trace_type: .scatter x: x_for_class y: y_for_class mode: 'markers' @@ -182,9 +181,8 @@ pub fn (o &Kmeans) plot() ! { } // Plot centroids - plt.add_trace( + plt.scatter( name: 'centroids' - trace_type: .scatter x: o.centroids.map(it[0]) y: o.centroids.map(it[1]) mode: 'markers' diff --git a/ml/knn.v b/ml/knn.v index aaee2f288..384607f20 100644 --- a/ml/knn.v +++ b/ml/knn.v @@ -207,7 +207,7 @@ pub fn (o &KNN) str() string { // plot method for visualizing the KNN model pub fn (o &KNN) plot() ! { mut plt := plot.new_plot() - plt.set_layout( + plt.layout( title: 'K-Nearest Neighbors' ) @@ -225,9 +225,8 @@ pub fn (o &KNN) plot() ! { } } - plt.add_trace( + plt.scatter( name: 'class #${i}' - trace_type: .scatter x: x_for_class y: y_for_class mode: 'markers' diff --git a/ml/linreg.v b/ml/linreg.v index c6473efb4..0c0c4c37c 100644 --- a/ml/linreg.v +++ b/ml/linreg.v @@ -164,13 +164,12 @@ pub fn (o &LinReg) plot() ! { // Rest of the code for plotting the graph mut plt := plot.new_plot() - plt.set_layout( + plt.layout( title: 'Linear Regression Example' ) - plt.add_trace( + plt.scatter( name: 'dataset' - trace_type: .scatter x: o.data.x.get_col(0) y: o.data.y mode: 'markers' @@ -180,9 +179,8 @@ pub fn (o &LinReg) plot() ! { } ) - plt.add_trace( + plt.scatter( name: 'linear regression' - trace_type: .scatter x: x_values y: y_values mode: 'lines' diff --git a/plot/plot.v b/plot/plot.v index dd4adf735..9d8ef8467 100644 --- a/plot/plot.v +++ b/plot/plot.v @@ -14,24 +14,52 @@ pub fn new_plot() Plot { return Plot{} } -pub fn (mut p Plot) add_trace(trace Trace) Plot { +pub fn (mut p Plot) scatter(trace ScatterTrace) Plot { + p.traces << trace + return p +} + +pub fn (mut p Plot) pie(trace PieTrace) Plot { + p.traces << trace + return p +} + +pub fn (mut p Plot) heatmap(trace HeatmapTrace) Plot { + p.traces << trace + return p +} + +pub fn (mut p Plot) surface(trace SurfaceTrace) Plot { + p.traces << trace + return p +} + +pub fn (mut p Plot) scatter3d(trace Scatter3DTrace) Plot { mut next_trace := trace - if trace.trace_type == .scatter3d { - z := next_trace.z - if z is [][]f64 { - next_trace.z = arrays.flatten(z) - } + z := next_trace.z + if z is [][]f64 { + next_trace.z = arrays.flatten(z) } p.traces << next_trace return p } -pub fn (mut p Plot) add_annotation(annotation Annotation) Plot { +pub fn (mut p Plot) bar(trace BarTrace) Plot { + p.traces << trace + return p +} + +pub fn (mut p Plot) histogram(trace HistogramTrace) Plot { + p.traces << trace + return p +} + +pub fn (mut p Plot) annotation(annotation Annotation) Plot { p.layout.annotations << annotation return p } -pub fn (mut p Plot) set_layout(layout Layout) Plot { +pub fn (mut p Plot) layout(layout Layout) Plot { mut next_layout := layout // Ensure that the layout range is specified correctly if next_layout.xaxis.range.len != 2 { diff --git a/plot/plot_test.v b/plot/plot_test.v index b67b09591..a0e7b7bf6 100644 --- a/plot/plot_test.v +++ b/plot/plot_test.v @@ -3,12 +3,11 @@ module plot fn test_bar() { mut plt := new_plot() - plt.add_trace( - trace_type: .bar + plt.bar( x: ['China', 'India', 'USA', 'Indonesia', 'Pakistan'] y: [1411778724.0, 1379217184, 331989449, 271350000, 225200000] ) - plt.set_layout( + plt.layout( title: 'Countries by population' ) plt.show()! diff --git a/plot/show.v b/plot/show.v index d9adab93b..52b1a7ec9 100644 --- a/plot/show.v +++ b/plot/show.v @@ -5,18 +5,37 @@ import time import vweb // port is the port to run the server on. If 0, it will run on the next available port. -const port = 0 +const port = 8000 struct App { vweb.Context plot Plot [vweb_global] } +type TracesWithTypeValue = Trace | string + +pub fn (p Plot) show() ! { + $if !test ? { + vweb.run(&App{ + plot: p + }, plot.port) + } +} + +fn preprocess_data_string(data string) string { + return data.replace(',"[]f64"', '').replace('"[]f64"', '').replace(',"[]string"', + '""').replace('"[]string"', '""') +} + pub fn (mut app App) index() vweb.Result { // For some reason this is not working yet - data := json.encode_pretty(app.plot.traces) - layout := json.encode_pretty(app.plot.layout) - spawn fn () { + traces_with_type := app.plot.traces.map({ + 'type': TracesWithTypeValue(it.trace_type()) + 'trace': TracesWithTypeValue(it) + }) + traces_with_type_json := preprocess_data_string(json.encode(traces_with_type)) + layout_json := json.encode(app.plot.layout) + go fn () { time.sleep(100 * time.millisecond) exit(0) }() @@ -30,21 +49,34 @@ pub fn (mut app App) index() vweb.Result { ') } - -pub fn (p Plot) show() ! { - $if !test ? { - vweb.run(&App{ - plot: p - }, plot.port) - } -} diff --git a/plot/trace.v b/plot/trace.v index af10f401f..66ac2a1e9 100644 --- a/plot/trace.v +++ b/plot/trace.v @@ -1,5 +1,6 @@ module plot +// Enum for trace types pub enum TraceType { scatter pie @@ -10,47 +11,135 @@ pub enum TraceType { histogram } -type XType = []f64 | []string -type YType = []f64 | []string -type ZType = [][]f64 | []f64 +// XType is a type for x-axis data +pub type XType = []f64 | []string +// YType is a type for y-axis data +pub type YType = []f64 | []string + +// ZType is a type for z-axis data +pub type ZType = [][]f64 | []f64 + +// CommonTrace is a struct for common trace properties +[params] +pub struct CommonTrace { +pub mut: + x XType + xbins map[string]f32 + y YType [omitempty] + z ZType [omitempty] + name string [omitempty] + mode string [omitempty] + marker Marker [omitempty] + line Line [omitempty] + pull []f64 [omitempty] + hole f64 [omitempty] + fill string [omitempty] + fillcolor string [omitempty] + customdata [][]string [omitempty] + colorscale string [omitempty] = 'Viridis' + textinfo string [omitempty] + text []string [omitempty] +} + +// ScatterTrace is a struct for Scatter trace type +[params] +pub struct ScatterTrace { + CommonTrace +} + +// PieTrace is a struct for Pie trace type +[params] +pub struct PieTrace { + CommonTrace +pub mut: + values []f64 [omitempty] + labels []string [omitempty] +} + +// HeatmapTrace is a struct for Heatmap trace type +[params] +pub struct HeatmapTrace { + CommonTrace +pub mut: + hovertemplate string [omitempty] + zsmooth string [omitempty] +} + +// SurfaceTrace is a struct for Surface trace type [params] -pub struct Trace { +pub struct SurfaceTrace { + CommonTrace pub mut: - trace_type TraceType [required] - x XType - xbins map[string]f32 - y YType [omitempty] - z ZType [omitempty] - values []f64 [omitempty] - labels []string [omitempty] - text []string [omitempty] - customdata [][]string [omitempty] - name string [omitempty] - mode string [omitempty] - marker Marker [omitempty] - line Line [omitempty] - pull []f64 [omitempty] - hole f64 [omitempty] - colorscale string [omitempty] = 'Viridis' - hovertemplate string [omitempty] - textinfo string [omitempty] - fill string [omitempty] - fillcolor string [omitempty] + hovertemplate string [omitempty] } +// Scatter3DTrace is a struct for Scatter3D trace type +[params] +pub struct Scatter3DTrace { + CommonTrace +} + +// BarTrace is a struct for Bar trace type +[params] +pub struct BarTrace { + CommonTrace +} + +// HistogramTrace is a struct for Histogram trace type +[params] +pub struct HistogramTrace { + CommonTrace +pub mut: + nbinsx int [omitempty] + nbinsy int [omitempty] + xbins Bins [omitempty] + histfunc string [omitempty] + marker Marker [omitempty] +} + +// Marker is a struct for marker properties in a trace pub struct Marker { pub mut: size []f64 [omitempty] color []string [omitempty] - opacity f64 [omitempty] - colorscale string [omitempty] + opacity f64 [omitempty] = 0.8 + colorscale string [omitempty] = 'Viridis' } +// Line is a struct for line properties in a trace pub struct Line { pub mut: color string [omitempty] - width f64 [omitempty] = 2.0 - // check Plotly docs for more dash types - dash string = 'solid' + width f64 [omitempty] = 2.0 + dash string [omitempty] = 'solid' +} + +// Bins is a struct for bin limits in a histogram trace +pub struct Bins { +pub mut: + start f64 + end f64 + size f64 +} + +// Trace is a sum type for representing different trace types +pub type Trace = BarTrace + | HeatmapTrace + | HistogramTrace + | PieTrace + | Scatter3DTrace + | ScatterTrace + | SurfaceTrace + +pub fn (t Trace) trace_type() string { + return match t { + BarTrace { 'bar' } + HeatmapTrace { 'heatmap' } + HistogramTrace { 'histogram' } + PieTrace { 'pie' } + Scatter3DTrace { 'scatter3d' } + ScatterTrace { 'scatter' } + SurfaceTrace { 'surface' } + } } From 3cae3ee90b2dc191d17c1df75c592eebd1c36ce0 Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 21:14:16 -0300 Subject: [PATCH 05/11] Updated plotly usage --- plot/.gitignore | 2 -- plot/show.v | 20 +++++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 plot/.gitignore diff --git a/plot/.gitignore b/plot/.gitignore deleted file mode 100644 index f5db557c8..000000000 --- a/plot/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.data* -.plotvenv* diff --git a/plot/show.v b/plot/show.v index 52b1a7ec9..badfbae7c 100644 --- a/plot/show.v +++ b/plot/show.v @@ -22,9 +22,19 @@ pub fn (p Plot) show() ! { } } -fn preprocess_data_string(data string) string { - return data.replace(',"[]f64"', '').replace('"[]f64"', '').replace(',"[]string"', - '""').replace('"[]string"', '""') +// TODO: This is a hack to allow the json encoder to work with sum types +fn encode[T](obj T) string { + strings_to_replace := [ + ',"[]f64"', + '"[]f64"', + ',"[]string"', + '"[]string"', + ] + mut obj_json := json.encode(obj) + for string_to_replace in strings_to_replace { + obj_json = obj_json.replace(string_to_replace, '') + } + return obj_json } pub fn (mut app App) index() vweb.Result { @@ -33,8 +43,8 @@ pub fn (mut app App) index() vweb.Result { 'type': TracesWithTypeValue(it.trace_type()) 'trace': TracesWithTypeValue(it) }) - traces_with_type_json := preprocess_data_string(json.encode(traces_with_type)) - layout_json := json.encode(app.plot.layout) + traces_with_type_json := encode(traces_with_type) + layout_json := encode(app.plot.layout) go fn () { time.sleep(100 * time.millisecond) exit(0) From 02a0a10b9a26fd7da681388e000c9d51ade675ed Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 21:23:54 -0300 Subject: [PATCH 06/11] Updated plotly usage --- plot/show.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plot/show.v b/plot/show.v index badfbae7c..4359a4daa 100644 --- a/plot/show.v +++ b/plot/show.v @@ -37,7 +37,8 @@ fn encode[T](obj T) string { return obj_json } -pub fn (mut app App) index() vweb.Result { +['/'] +pub fn (mut app App) plotly() vweb.Result { // For some reason this is not working yet traces_with_type := app.plot.traces.map({ 'type': TracesWithTypeValue(it.trace_type()) From d2f4bd3b282ec7946c22e01df8ba4429f3d920cc Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 21:29:05 -0300 Subject: [PATCH 07/11] Updated plotly usage --- examples/data_analysis_example/main.v | 4 +- examples/fft_plot_example/main.v | 2 +- examples/plot_annotated_pie_chart/main.v | 2 +- examples/plot_bar/main.v | 2 +- examples/plot_basic_heatmap/main.v | 2 +- examples/plot_bubble_chart/main.v | 2 +- examples/plot_grouped_bar_chart/main.v | 2 +- examples/plot_heatmap_golden_ratio/main.v | 2 +- examples/plot_histogram/main.v | 2 +- examples/plot_line_plot_with_areas/main.v | 2 +- examples/plot_pie/main.v | 2 +- examples/plot_ripple_surface/main.v | 2 +- examples/plot_saddle_surface/main.v | 2 +- examples/plot_scatter/main.v | 2 +- examples/plot_scatter3d_1/main.v | 2 +- examples/plot_scatter3d_2/main.v | 2 +- examples/plot_scatter3d_easing/main.v | 2 +- examples/plot_scatter_colorscale/main.v | 2 +- examples/plot_scatter_easing/main.v | 2 +- examples/plot_scatter_with_bars/main.v | 2 +- examples/plot_scatter_with_histogram/main.v | 2 +- examples/plot_scatter_with_regression/main.v | 2 +- examples/plot_shaded_area_sin/main.v | 2 +- examples/plot_sin_cos_surface/main.v | 2 +- examples/plot_surface/main.v | 2 +- examples/plot_surface_easing/main.v | 2 +- examples/roots_bisection_solver/main.v | 2 +- ml/kmeans.v | 2 +- ml/knn.v | 2 +- ml/linreg.v | 2 +- plot/plot.v | 48 ++++++++++++++------ plot/plot_test.v | 2 +- 32 files changed, 66 insertions(+), 46 deletions(-) diff --git a/examples/data_analysis_example/main.v b/examples/data_analysis_example/main.v index 6d6a3a530..cbfa53eee 100644 --- a/examples/data_analysis_example/main.v +++ b/examples/data_analysis_example/main.v @@ -62,7 +62,7 @@ fn main() { ])! // Visualize data in a 3D scatter plot - mut plt_3d := plot.new_plot() + mut plt_3d := plot.Plot.new() x1 := data.x.get_col(0) x2 := data.x.get_col(1) @@ -131,7 +131,7 @@ fn main() { stat.update() // Visualize statistics in a bar chart - mut plt_bars := plot.new_plot() + mut plt_bars := plot.Plot.new() plt_bars.bar( x: []string{len: stat.mean_x.len, init: 'Class ${index}'} diff --git a/examples/fft_plot_example/main.v b/examples/fft_plot_example/main.v index 4059fb8dc..51ba8881d 100644 --- a/examples/fft_plot_example/main.v +++ b/examples/fft_plot_example/main.v @@ -22,7 +22,7 @@ fn main() { spectrum := signal.clone() // Create a scatter plot for the signal and its spectrum - mut plt := plot.new_plot() + mut plt := plot.Plot.new() // Add a scatter plot for the original signal plt.scatter( diff --git a/examples/plot_annotated_pie_chart/main.v b/examples/plot_annotated_pie_chart/main.v index f9a83aa67..53f9f740d 100644 --- a/examples/plot_annotated_pie_chart/main.v +++ b/examples/plot_annotated_pie_chart/main.v @@ -6,7 +6,7 @@ fn main() { labels := ['Apples', 'Bananas', 'Cherries', 'Grapes'] values := [25.0, 30, 15, 30] - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.pie( labels: labels values: values diff --git a/examples/plot_bar/main.v b/examples/plot_bar/main.v index 2cf02e1e1..8ae905e9f 100644 --- a/examples/plot_bar/main.v +++ b/examples/plot_bar/main.v @@ -3,7 +3,7 @@ module main import vsl.plot fn main() { - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.bar( x: ['China', 'India', 'USA', 'Indonesia', 'Pakistan'] diff --git a/examples/plot_basic_heatmap/main.v b/examples/plot_basic_heatmap/main.v index 7beaf676b..c0eb735f8 100644 --- a/examples/plot_basic_heatmap/main.v +++ b/examples/plot_basic_heatmap/main.v @@ -6,7 +6,7 @@ z := [[1.0, 0, 30, 50, 1], [20.0, 1, 60, 80, 30], [30.0, 60, 1, -10, 20]] x := ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] y := ['Morning', 'Afternoon', 'Evening'] -mut plt := plot.new_plot() +mut plt := plot.Plot.new() plt.heatmap( x: x diff --git a/examples/plot_bubble_chart/main.v b/examples/plot_bubble_chart/main.v index 8294ec9cc..68ad2a5aa 100644 --- a/examples/plot_bubble_chart/main.v +++ b/examples/plot_bubble_chart/main.v @@ -7,7 +7,7 @@ fn main() { y := []f64{len: 100, init: f64(index) * 0.1} size := []f64{len: 10, init: f64(index) * 10.0} - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( x: x y: y diff --git a/examples/plot_grouped_bar_chart/main.v b/examples/plot_grouped_bar_chart/main.v index 1c2447f4d..d0fcdd116 100644 --- a/examples/plot_grouped_bar_chart/main.v +++ b/examples/plot_grouped_bar_chart/main.v @@ -7,7 +7,7 @@ fn main() { values1 := [10.0, 15, 7, 12] values2 := [8.0, 14, 5, 10] - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.bar( x: categories y: values1 diff --git a/examples/plot_heatmap_golden_ratio/main.v b/examples/plot_heatmap_golden_ratio/main.v index f7e8da879..e8329e3ef 100644 --- a/examples/plot_heatmap_golden_ratio/main.v +++ b/examples/plot_heatmap_golden_ratio/main.v @@ -24,7 +24,7 @@ z := [[13.0, 3, 3, 5], [13.0, 2, 1, 5], [13.0, 10, 11, 12], [13.0, 8, 8, 8]] // x := r*math.cos(theta) // y := r*math.sin(theta) -mut plt := plot.new_plot() +mut plt := plot.Plot.new() plt.heatmap( x: xe diff --git a/examples/plot_histogram/main.v b/examples/plot_histogram/main.v index 1aa4c0105..f25995c33 100644 --- a/examples/plot_histogram/main.v +++ b/examples/plot_histogram/main.v @@ -9,7 +9,7 @@ mut x1 := []f64{cap: 1000} for _ in 1 .. 1000 { x1 << rand.f64n(100) or { 0 } } -mut plt := plot.new_plot() +mut plt := plot.Plot.new() plt.histogram( x: x1 xbins: { diff --git a/examples/plot_line_plot_with_areas/main.v b/examples/plot_line_plot_with_areas/main.v index 66ac1e562..6af4f913a 100644 --- a/examples/plot_line_plot_with_areas/main.v +++ b/examples/plot_line_plot_with_areas/main.v @@ -8,7 +8,7 @@ fn main() { y1 := x.map(math.sin(it)) y2 := x.map(math.cos(it)) - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( x: x y: y1 diff --git a/examples/plot_pie/main.v b/examples/plot_pie/main.v index e896db4ff..43f5f29da 100644 --- a/examples/plot_pie/main.v +++ b/examples/plot_pie/main.v @@ -3,7 +3,7 @@ module main import vsl.plot fn main() { - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.pie( labels: ['Nitrogen', 'Oxygen', 'Argon', 'Other'] diff --git a/examples/plot_ripple_surface/main.v b/examples/plot_ripple_surface/main.v index 15baf79e2..442d4018e 100644 --- a/examples/plot_ripple_surface/main.v +++ b/examples/plot_ripple_surface/main.v @@ -18,7 +18,7 @@ fn main() { z << row } - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.surface( x: x y: y diff --git a/examples/plot_saddle_surface/main.v b/examples/plot_saddle_surface/main.v index 8df68b528..372662d74 100644 --- a/examples/plot_saddle_surface/main.v +++ b/examples/plot_saddle_surface/main.v @@ -17,7 +17,7 @@ fn main() { z << row } - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.surface( x: x y: y diff --git a/examples/plot_scatter/main.v b/examples/plot_scatter/main.v index 31e459c38..2027eb36f 100644 --- a/examples/plot_scatter/main.v +++ b/examples/plot_scatter/main.v @@ -20,7 +20,7 @@ y := [ ] x := util.arange(y.len).map(f64(it)) -mut plt := plot.new_plot() +mut plt := plot.Plot.new() plt.scatter( x: x y: y diff --git a/examples/plot_scatter3d_1/main.v b/examples/plot_scatter3d_1/main.v index 6749d083a..1173d3771 100644 --- a/examples/plot_scatter3d_1/main.v +++ b/examples/plot_scatter3d_1/main.v @@ -22,7 +22,7 @@ fn main() { x := util.arange(y.len).map(f64(it)) z := util.arange(y.len).map(util.arange(y.len).map(f64(it * it))) - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter3d( x: x y: y diff --git a/examples/plot_scatter3d_2/main.v b/examples/plot_scatter3d_2/main.v index 27be00dc6..9eda8acf2 100644 --- a/examples/plot_scatter3d_2/main.v +++ b/examples/plot_scatter3d_2/main.v @@ -15,7 +15,7 @@ fn main() { z << val } - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter3d( x: x y: y diff --git a/examples/plot_scatter3d_easing/main.v b/examples/plot_scatter3d_easing/main.v index 96c43851e..7f6fa2d4e 100644 --- a/examples/plot_scatter3d_easing/main.v +++ b/examples/plot_scatter3d_easing/main.v @@ -15,7 +15,7 @@ fn main() { z_values := easings.animate(easings.bounce_ease_in_out, 0.0, 1.0, frames) // Create the Scatter3D plot - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter3d( name: 'Easing Scatter3D' x: x_values diff --git a/examples/plot_scatter_colorscale/main.v b/examples/plot_scatter_colorscale/main.v index 5935b6b9d..0cecfbc35 100644 --- a/examples/plot_scatter_colorscale/main.v +++ b/examples/plot_scatter_colorscale/main.v @@ -20,7 +20,7 @@ y := [ ] x := util.arange(y.len).map(f64(it)) -mut plt := plot.new_plot() +mut plt := plot.Plot.new() plt.scatter( x: x y: y diff --git a/examples/plot_scatter_easing/main.v b/examples/plot_scatter_easing/main.v index da454e1c1..79c855ed6 100644 --- a/examples/plot_scatter_easing/main.v +++ b/examples/plot_scatter_easing/main.v @@ -14,7 +14,7 @@ fn main() { y_values := easings.animate(easings.elastic_ease_out, 0.0, 1.0, frames) // Create the Scatter plot - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( name: 'Easing Scatter' x: x_values diff --git a/examples/plot_scatter_with_bars/main.v b/examples/plot_scatter_with_bars/main.v index ce5c21ca2..a5660344d 100644 --- a/examples/plot_scatter_with_bars/main.v +++ b/examples/plot_scatter_with_bars/main.v @@ -7,7 +7,7 @@ fn main() { x := util.lin_space(1.0, 10.0, 10) y := x.map(it * it) - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( x: x y: y diff --git a/examples/plot_scatter_with_histogram/main.v b/examples/plot_scatter_with_histogram/main.v index 2e83ed99b..96a8264ae 100644 --- a/examples/plot_scatter_with_histogram/main.v +++ b/examples/plot_scatter_with_histogram/main.v @@ -11,7 +11,7 @@ fn main() { x << rand.f64n(100) or { 0 } } - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( x: x y: x diff --git a/examples/plot_scatter_with_regression/main.v b/examples/plot_scatter_with_regression/main.v index d1a3b4b9b..47c15a8db 100644 --- a/examples/plot_scatter_with_regression/main.v +++ b/examples/plot_scatter_with_regression/main.v @@ -6,7 +6,7 @@ fn main() { x := []f64{len: 100, init: f64(index) * 0.1} y := [1.2, 2.1, 3.0, 4.5, 5.8, 7.0, 8.2, 9.1, 10.5, 11.8] - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( x: x y: y diff --git a/examples/plot_shaded_area_sin/main.v b/examples/plot_shaded_area_sin/main.v index b571e028d..83d0044f1 100644 --- a/examples/plot_shaded_area_sin/main.v +++ b/examples/plot_shaded_area_sin/main.v @@ -7,7 +7,7 @@ fn main() { x := []f64{len: 100, init: f64(index) * 0.1} y := x.map(math.sin(it)) - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.scatter( x: x y: y diff --git a/examples/plot_sin_cos_surface/main.v b/examples/plot_sin_cos_surface/main.v index 62a6a2ffd..4d8ab3cbd 100644 --- a/examples/plot_sin_cos_surface/main.v +++ b/examples/plot_sin_cos_surface/main.v @@ -17,7 +17,7 @@ fn main() { z << row } - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.surface( x: x y: y diff --git a/examples/plot_surface/main.v b/examples/plot_surface/main.v index bad46f9b3..f383fa627 100644 --- a/examples/plot_surface/main.v +++ b/examples/plot_surface/main.v @@ -17,7 +17,7 @@ fn main() { z << row } - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.surface( x: x y: y diff --git a/examples/plot_surface_easing/main.v b/examples/plot_surface_easing/main.v index 069e635ec..b6f7ebe8a 100644 --- a/examples/plot_surface_easing/main.v +++ b/examples/plot_surface_easing/main.v @@ -13,7 +13,7 @@ fn main() { z_values := easings.animate(easings.bounce_ease_in_out, 0.0, 1.0, frames) // Create the Surface plot - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.surface( name: 'Easing Surface' x: x_values diff --git a/examples/roots_bisection_solver/main.v b/examples/roots_bisection_solver/main.v index e38053632..142368f0c 100644 --- a/examples/roots_bisection_solver/main.v +++ b/examples/roots_bisection_solver/main.v @@ -34,7 +34,7 @@ assert float64.soclose(result.x, expected, solver.epsabs) println('x = ${result.x}') -mut plt := plot.new_plot() +mut plt := plot.Plot.new() x := util.lin_space(0.0, 3.0, 100) y := x.map(f_cos(it, []f64{})) diff --git a/ml/kmeans.v b/ml/kmeans.v index 941a1951b..8716cc096 100644 --- a/ml/kmeans.v +++ b/ml/kmeans.v @@ -149,7 +149,7 @@ pub fn (o &Kmeans) str() string { // plot method for visualizing the clustering pub fn (o &Kmeans) plot() ! { - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.layout( title: 'K-means Clustering' ) diff --git a/ml/knn.v b/ml/knn.v index 384607f20..62a1239bf 100644 --- a/ml/knn.v +++ b/ml/knn.v @@ -206,7 +206,7 @@ pub fn (o &KNN) str() string { // plot method for visualizing the KNN model pub fn (o &KNN) plot() ! { - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.layout( title: 'K-Nearest Neighbors' ) diff --git a/ml/linreg.v b/ml/linreg.v index 0c0c4c37c..be38899e4 100644 --- a/ml/linreg.v +++ b/ml/linreg.v @@ -163,7 +163,7 @@ pub fn (o &LinReg) plot() ! { y_values := x_values.map(o.predict([it])) // Rest of the code for plotting the graph - mut plt := plot.new_plot() + mut plt := plot.Plot.new() plt.layout( title: 'Linear Regression Example' ) diff --git a/plot/plot.v b/plot/plot.v index 9d8ef8467..de630c3e9 100644 --- a/plot/plot.v +++ b/plot/plot.v @@ -10,55 +10,75 @@ pub mut: layout Layout } -pub fn new_plot() Plot { +pub fn Plot.new() Plot { return Plot{} } -pub fn (mut p Plot) scatter(trace ScatterTrace) Plot { +// add_trace adds a trace to the plot +[inline] +fn (mut p Plot) add_trace[T](trace T) Plot { p.traces << trace return p } +// scatter adds a scatter trace to the plot +[inline] +pub fn (mut p Plot) scatter(trace ScatterTrace) Plot { + return p.add_trace(trace) +} + +// pie adds a pie trace to the plot +[inline] pub fn (mut p Plot) pie(trace PieTrace) Plot { - p.traces << trace - return p + return p.add_trace(trace) } +// heatmap adds a heatmap trace to the plot +[inline] pub fn (mut p Plot) heatmap(trace HeatmapTrace) Plot { - p.traces << trace - return p + return p.add_trace(trace) } +// surface adds a surface trace to the plot +[inline] pub fn (mut p Plot) surface(trace SurfaceTrace) Plot { - p.traces << trace - return p + return p.add_trace(trace) } +// scatter3d adds a scatter3d trace to the plot. +// If the z value is a 2D array, it is flattened +// to a 1D array +[inline] pub fn (mut p Plot) scatter3d(trace Scatter3DTrace) Plot { mut next_trace := trace z := next_trace.z if z is [][]f64 { next_trace.z = arrays.flatten(z) } - p.traces << next_trace - return p + return p.add_trace(next_trace) } +// bar adds a bar trace to the plot +[inline] pub fn (mut p Plot) bar(trace BarTrace) Plot { - p.traces << trace - return p + return p.add_trace(trace) } +// histogram adds a histogram trace to the plot +[inline] pub fn (mut p Plot) histogram(trace HistogramTrace) Plot { - p.traces << trace - return p + return p.add_trace(trace) } +// box adds a box trace to the plot +[inline] pub fn (mut p Plot) annotation(annotation Annotation) Plot { p.layout.annotations << annotation return p } +// layout sets the layout of the plot +[inline] pub fn (mut p Plot) layout(layout Layout) Plot { mut next_layout := layout // Ensure that the layout range is specified correctly diff --git a/plot/plot_test.v b/plot/plot_test.v index a0e7b7bf6..e2da42fcb 100644 --- a/plot/plot_test.v +++ b/plot/plot_test.v @@ -1,7 +1,7 @@ module plot fn test_bar() { - mut plt := new_plot() + mut plt := Plot.new() plt.bar( x: ['China', 'India', 'USA', 'Indonesia', 'Pakistan'] From 06d845d244509e9433ff338efcee0d2daae8393b Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 22:34:15 -0300 Subject: [PATCH 08/11] Updated plotly usage --- examples/io_h5_dataset/main.v | 2 +- examples/io_h5_relax/main.v | 2 +- {io => inout}/h5/README.md | 0 {io => inout}/h5/TODO.md | 0 {io => inout}/h5/_cflags.c.v | 0 {io => inout}/h5/hdf5_nix.c.v | 0 {io => inout}/h5/readhdf5_test.v | 0 {io => inout}/h5/three_d_test.v | 0 {io => inout}/h5/two_d_test.v | 0 {io => inout}/h5/typeshdf5_test.v | 0 {io => inout}/h5/utils.v | 0 {io => inout}/h5/v.mod | 0 12 files changed, 2 insertions(+), 2 deletions(-) rename {io => inout}/h5/README.md (100%) rename {io => inout}/h5/TODO.md (100%) rename {io => inout}/h5/_cflags.c.v (100%) rename {io => inout}/h5/hdf5_nix.c.v (100%) rename {io => inout}/h5/readhdf5_test.v (100%) rename {io => inout}/h5/three_d_test.v (100%) rename {io => inout}/h5/two_d_test.v (100%) rename {io => inout}/h5/typeshdf5_test.v (100%) rename {io => inout}/h5/utils.v (100%) rename {io => inout}/h5/v.mod (100%) diff --git a/examples/io_h5_dataset/main.v b/examples/io_h5_dataset/main.v index 6f3e6829c..3043f4e17 100644 --- a/examples/io_h5_dataset/main.v +++ b/examples/io_h5_dataset/main.v @@ -1,4 +1,4 @@ -import vsl.io.h5 +import vsl.inout.h5 import math.stats import rand diff --git a/examples/io_h5_relax/main.v b/examples/io_h5_relax/main.v index a8eb41ffc..5e00764ea 100644 --- a/examples/io_h5_relax/main.v +++ b/examples/io_h5_relax/main.v @@ -1,4 +1,4 @@ -import vsl.io.h5 +import vsl.inout.h5 import math // A simple 1d relaxation problem. Write the results diff --git a/io/h5/README.md b/inout/h5/README.md similarity index 100% rename from io/h5/README.md rename to inout/h5/README.md diff --git a/io/h5/TODO.md b/inout/h5/TODO.md similarity index 100% rename from io/h5/TODO.md rename to inout/h5/TODO.md diff --git a/io/h5/_cflags.c.v b/inout/h5/_cflags.c.v similarity index 100% rename from io/h5/_cflags.c.v rename to inout/h5/_cflags.c.v diff --git a/io/h5/hdf5_nix.c.v b/inout/h5/hdf5_nix.c.v similarity index 100% rename from io/h5/hdf5_nix.c.v rename to inout/h5/hdf5_nix.c.v diff --git a/io/h5/readhdf5_test.v b/inout/h5/readhdf5_test.v similarity index 100% rename from io/h5/readhdf5_test.v rename to inout/h5/readhdf5_test.v diff --git a/io/h5/three_d_test.v b/inout/h5/three_d_test.v similarity index 100% rename from io/h5/three_d_test.v rename to inout/h5/three_d_test.v diff --git a/io/h5/two_d_test.v b/inout/h5/two_d_test.v similarity index 100% rename from io/h5/two_d_test.v rename to inout/h5/two_d_test.v diff --git a/io/h5/typeshdf5_test.v b/inout/h5/typeshdf5_test.v similarity index 100% rename from io/h5/typeshdf5_test.v rename to inout/h5/typeshdf5_test.v diff --git a/io/h5/utils.v b/inout/h5/utils.v similarity index 100% rename from io/h5/utils.v rename to inout/h5/utils.v diff --git a/io/h5/v.mod b/inout/h5/v.mod similarity index 100% rename from io/h5/v.mod rename to inout/h5/v.mod From 730fb50923033f092c9f463c7c44cac67e3d4b13 Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 22:39:17 -0300 Subject: [PATCH 09/11] Updated plotly usage --- examples/plot_histogram/main.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/plot_histogram/main.v b/examples/plot_histogram/main.v index f25995c33..402e06e7b 100644 --- a/examples/plot_histogram/main.v +++ b/examples/plot_histogram/main.v @@ -12,10 +12,10 @@ for _ in 1 .. 1000 { mut plt := plot.Plot.new() plt.histogram( x: x1 - xbins: { - 'start': f32(0) - 'end': f32(100) - 'size': 2 + xbins: plot.Bins{ + start: 0.0 + end: 100.0 + size: 2 } ) plt.layout( From e4587a6c9cf693bca43a2754ffd66463e7a12dcd Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 22:41:05 -0300 Subject: [PATCH 10/11] Updated plotly usage --- examples/plot_histogram/main.v | 8 +++----- examples/plot_scatter_with_histogram/main.v | 5 +---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/plot_histogram/main.v b/examples/plot_histogram/main.v index 402e06e7b..6d0eb0c09 100644 --- a/examples/plot_histogram/main.v +++ b/examples/plot_histogram/main.v @@ -5,13 +5,11 @@ import vsl.plot rand.seed([u32(1), 42]) -mut x1 := []f64{cap: 1000} -for _ in 1 .. 1000 { - x1 << rand.f64n(100) or { 0 } -} +x := []f64{len: 1000, init: (0 * index) + rand.f64n(100) or { 0 }} + mut plt := plot.Plot.new() plt.histogram( - x: x1 + x: x xbins: plot.Bins{ start: 0.0 end: 100.0 diff --git a/examples/plot_scatter_with_histogram/main.v b/examples/plot_scatter_with_histogram/main.v index 96a8264ae..2ba11c7f7 100644 --- a/examples/plot_scatter_with_histogram/main.v +++ b/examples/plot_scatter_with_histogram/main.v @@ -6,10 +6,7 @@ import vsl.plot fn main() { rand.seed([u32(1), 42]) - mut x := []f64{cap: 100} - for _ in 1 .. 100 { - x << rand.f64n(100) or { 0 } - } + x := []f64{len: 100, init: (0 * index) + rand.f64n(100) or { 0 }} mut plt := plot.Plot.new() plt.scatter( From 6baf9fa631c26f6e78ed1fb0a48097564dae0eb6 Mon Sep 17 00:00:00 2001 From: ulises-jeremias Date: Mon, 16 Oct 2023 22:53:47 -0300 Subject: [PATCH 11/11] Fixed types --- fft/fft.c.v | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fft/fft.c.v b/fft/fft.c.v index 37c35fc5f..6f59b937f 100644 --- a/fft/fft.c.v +++ b/fft/fft.c.v @@ -2,6 +2,26 @@ module fft type FftSizeT = u64 +type C.cfft_plan_f32 = voidptr + +type C.rfft_plan_f32 = voidptr + +type C.cfft_plan_f64 = voidptr + +type C.rfft_plan_f64 = voidptr + +type C.cfftp_plan_f32 = voidptr + +type C.cfftblue_plan_f32 = voidptr + +type C.cfftp_plan_f64 = voidptr + +type C.cfftblue_plan_f64 = voidptr + +type C.rfftp_plan_f32 = voidptr + +type C.rfftblue_plan_f32 = voidptr + struct C.cfft_plan_i_f32 { packplan C.cfftp_plan_f32 blueplan C.cfftblue_plan_f32