From 3d7569a592febb68006d64cb9446249f80b04f93 Mon Sep 17 00:00:00 2001 From: Ulises Jeremias Date: Mon, 16 Oct 2023 23:15:55 -0300 Subject: [PATCH] Removing python for vsl.plot - WIP (#173) * WIP: * WIP: * Updated default port * Updated plotly usage * Updated plotly usage * Updated plotly usage * Updated plotly usage * Updated plotly usage * Updated plotly usage * Updated plotly usage * Fixed types --- examples/data_analysis_example/main.v | 27 ++-- examples/fft_plot_example/main.v | 10 +- examples/io_h5_dataset/main.v | 2 +- examples/io_h5_relax/main.v | 2 +- examples/plot_annotated_pie_chart/main.v | 7 +- examples/plot_bar/main.v | 7 +- examples/plot_basic_heatmap/main.v | 7 +- examples/plot_bubble_chart/main.v | 7 +- examples/plot_grouped_bar_chart/main.v | 10 +- examples/plot_heatmap_golden_ratio/main.v | 7 +- examples/plot_histogram/main.v | 23 ++- examples/plot_line_plot_with_areas/main.v | 10 +- examples/plot_pie/main.v | 29 ++-- examples/plot_ripple_surface/main.v | 7 +- examples/plot_saddle_surface/main.v | 7 +- examples/plot_scatter/main.v | 7 +- examples/plot_scatter3d_1/main.v | 7 +- examples/plot_scatter3d_2/main.v | 7 +- examples/plot_scatter3d_easing/main.v | 7 +- examples/plot_scatter_colorscale/main.v | 7 +- examples/plot_scatter_easing/main.v | 7 +- examples/plot_scatter_with_bars/main.v | 10 +- examples/plot_scatter_with_histogram/main.v | 15 +- examples/plot_scatter_with_regression/main.v | 10 +- examples/plot_shaded_area_sin/main.v | 10 +- examples/plot_sin_cos_surface/main.v | 7 +- examples/plot_surface/main.v | 7 +- examples/plot_surface_easing/main.v | 7 +- examples/roots_bisection_solver/main.v | 10 +- fft/fft.c.v | 20 +++ {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 ml/kmeans.v | 10 +- ml/knn.v | 7 +- ml/linreg.v | 10 +- plot/.gitignore | 2 - plot/plot.v | 70 +++++++-- plot/plot_test.v | 7 +- plot/scripts/create-venv.sh | 25 ---- plot/scripts/plotter.py | 91 ------------ plot/scripts/python.sh | 21 --- plot/scripts/run.sh | 24 --- plot/show.v | 131 ++++++++++------- plot/trace.v | 147 +++++++++++++++---- 52 files changed, 407 insertions(+), 438 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%) delete mode 100644 plot/.gitignore 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/examples/data_analysis_example/main.v b/examples/data_analysis_example/main.v index ea581a5f8..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) @@ -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{ @@ -134,24 +131,22 @@ fn main() { stat.update() // Visualize statistics in a bar chart - mut plt_bars := plot.new_plot() + mut plt_bars := plot.Plot.new() - 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..51ba8881d 100644 --- a/examples/fft_plot_example/main.v +++ b/examples/fft_plot_example/main.v @@ -22,11 +22,10 @@ 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.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/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/examples/plot_annotated_pie_chart/main.v b/examples/plot_annotated_pie_chart/main.v index 572f34024..53f9f740d 100644 --- a/examples/plot_annotated_pie_chart/main.v +++ b/examples/plot_annotated_pie_chart/main.v @@ -6,14 +6,13 @@ fn main() { labels := ['Apples', 'Bananas', 'Cherries', 'Grapes'] values := [25.0, 30, 15, 30] - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .pie + mut plt := plot.Plot.new() + 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..8ae905e9f 100644 --- a/examples/plot_bar/main.v +++ b/examples/plot_bar/main.v @@ -3,14 +3,13 @@ module main import vsl.plot fn main() { - mut plt := plot.new_plot() + mut plt := plot.Plot.new() - 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..c0eb735f8 100644 --- a/examples/plot_basic_heatmap/main.v +++ b/examples/plot_basic_heatmap/main.v @@ -6,15 +6,14 @@ 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.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..68ad2a5aa 100644 --- a/examples/plot_bubble_chart/main.v +++ b/examples/plot_bubble_chart/main.v @@ -7,9 +7,8 @@ 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() - plt.add_trace( - trace_type: .scatter + mut plt := plot.Plot.new() + 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..d0fcdd116 100644 --- a/examples/plot_grouped_bar_chart/main.v +++ b/examples/plot_grouped_bar_chart/main.v @@ -7,20 +7,18 @@ fn main() { values1 := [10.0, 15, 7, 12] values2 := [8.0, 14, 5, 10] - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .bar + mut plt := plot.Plot.new() + 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..e8329e3ef 100644 --- a/examples/plot_heatmap_golden_ratio/main.v +++ b/examples/plot_heatmap_golden_ratio/main.v @@ -24,15 +24,14 @@ 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.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..6d0eb0c09 100644 --- a/examples/plot_histogram/main.v +++ b/examples/plot_histogram/main.v @@ -5,21 +5,18 @@ import vsl.plot rand.seed([u32(1), 42]) -mut x1 := []f64{cap: 1000} -for _ in 1 .. 1000 { - x1 << rand.f64n(100) or { 0 } -} -mut plt := plot.new_plot() -plt.add_trace( - trace_type: .histogram - x: x1 - xbins: { - 'start': f32(0) - 'end': f32(100) - 'size': 2 +x := []f64{len: 1000, init: (0 * index) + rand.f64n(100) or { 0 }} + +mut plt := plot.Plot.new() +plt.histogram( + x: x + xbins: plot.Bins{ + start: 0.0 + end: 100.0 + 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..6af4f913a 100644 --- a/examples/plot_line_plot_with_areas/main.v +++ b/examples/plot_line_plot_with_areas/main.v @@ -8,9 +8,8 @@ fn main() { y1 := x.map(math.sin(it)) y2 := x.map(math.cos(it)) - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + mut plt := plot.Plot.new() + 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..43f5f29da 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.Plot.new() -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..442d4018e 100644 --- a/examples/plot_ripple_surface/main.v +++ b/examples/plot_ripple_surface/main.v @@ -18,15 +18,14 @@ fn main() { z << row } - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + mut plt := plot.Plot.new() + 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..372662d74 100644 --- a/examples/plot_saddle_surface/main.v +++ b/examples/plot_saddle_surface/main.v @@ -17,15 +17,14 @@ fn main() { z << row } - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + mut plt := plot.Plot.new() + 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..2027eb36f 100644 --- a/examples/plot_scatter/main.v +++ b/examples/plot_scatter/main.v @@ -20,9 +20,8 @@ y := [ ] x := util.arange(y.len).map(f64(it)) -mut plt := plot.new_plot() -plt.add_trace( - trace_type: .scatter +mut plt := plot.Plot.new() +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..1173d3771 100644 --- a/examples/plot_scatter3d_1/main.v +++ b/examples/plot_scatter3d_1/main.v @@ -22,9 +22,8 @@ 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() - plt.add_trace( - trace_type: .scatter3d + mut plt := plot.Plot.new() + 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..9eda8acf2 100644 --- a/examples/plot_scatter3d_2/main.v +++ b/examples/plot_scatter3d_2/main.v @@ -15,9 +15,8 @@ fn main() { z << val } - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter3d + mut plt := plot.Plot.new() + 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..7f6fa2d4e 100644 --- a/examples/plot_scatter3d_easing/main.v +++ b/examples/plot_scatter3d_easing/main.v @@ -15,10 +15,9 @@ 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() - plt.add_trace( + mut plt := plot.Plot.new() + 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..0cecfbc35 100644 --- a/examples/plot_scatter_colorscale/main.v +++ b/examples/plot_scatter_colorscale/main.v @@ -20,9 +20,8 @@ y := [ ] x := util.arange(y.len).map(f64(it)) -mut plt := plot.new_plot() -plt.add_trace( - trace_type: .scatter +mut plt := plot.Plot.new() +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..79c855ed6 100644 --- a/examples/plot_scatter_easing/main.v +++ b/examples/plot_scatter_easing/main.v @@ -14,10 +14,9 @@ fn main() { y_values := easings.animate(easings.elastic_ease_out, 0.0, 1.0, frames) // Create the Scatter plot - mut plt := plot.new_plot() - plt.add_trace( + mut plt := plot.Plot.new() + 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..a5660344d 100644 --- a/examples/plot_scatter_with_bars/main.v +++ b/examples/plot_scatter_with_bars/main.v @@ -7,9 +7,8 @@ fn main() { x := util.lin_space(1.0, 10.0, 10) y := x.map(it * it) - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + mut plt := plot.Plot.new() + 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..2ba11c7f7 100644 --- a/examples/plot_scatter_with_histogram/main.v +++ b/examples/plot_scatter_with_histogram/main.v @@ -6,14 +6,10 @@ 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.new_plot() - plt.add_trace( - trace_type: .scatter + mut plt := plot.Plot.new() + plt.scatter( x: x y: x mode: 'markers' @@ -22,11 +18,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..47c15a8db 100644 --- a/examples/plot_scatter_with_regression/main.v +++ b/examples/plot_scatter_with_regression/main.v @@ -6,9 +6,8 @@ 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() - plt.add_trace( - trace_type: .scatter + mut plt := plot.Plot.new() + 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..83d0044f1 100644 --- a/examples/plot_shaded_area_sin/main.v +++ b/examples/plot_shaded_area_sin/main.v @@ -7,9 +7,8 @@ fn main() { x := []f64{len: 100, init: f64(index) * 0.1} y := x.map(math.sin(it)) - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .scatter + mut plt := plot.Plot.new() + 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..4d8ab3cbd 100644 --- a/examples/plot_sin_cos_surface/main.v +++ b/examples/plot_sin_cos_surface/main.v @@ -17,15 +17,14 @@ fn main() { z << row } - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + mut plt := plot.Plot.new() + 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..f383fa627 100644 --- a/examples/plot_surface/main.v +++ b/examples/plot_surface/main.v @@ -17,15 +17,14 @@ fn main() { z << row } - mut plt := plot.new_plot() - plt.add_trace( - trace_type: .surface + mut plt := plot.Plot.new() + 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..b6f7ebe8a 100644 --- a/examples/plot_surface_easing/main.v +++ b/examples/plot_surface_easing/main.v @@ -13,16 +13,15 @@ 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() - plt.add_trace( + mut plt := plot.Plot.new() + 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..142368f0c 100644 --- a/examples/roots_bisection_solver/main.v +++ b/examples/roots_bisection_solver/main.v @@ -34,13 +34,12 @@ 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{})) -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/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 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 diff --git a/ml/kmeans.v b/ml/kmeans.v index d0255ee37..8716cc096 100644 --- a/ml/kmeans.v +++ b/ml/kmeans.v @@ -149,8 +149,8 @@ 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( + mut plt := plot.Plot.new() + 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..62a1239bf 100644 --- a/ml/knn.v +++ b/ml/knn.v @@ -206,8 +206,8 @@ 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( + mut plt := plot.Plot.new() + 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..be38899e4 100644 --- a/ml/linreg.v +++ b/ml/linreg.v @@ -163,14 +163,13 @@ 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() - plt.set_layout( + mut plt := plot.Plot.new() + 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/.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/plot.v b/plot/plot.v index dd4adf735..de630c3e9 100644 --- a/plot/plot.v +++ b/plot/plot.v @@ -10,28 +10,76 @@ pub mut: layout Layout } -pub fn new_plot() Plot { +pub fn Plot.new() Plot { return Plot{} } -pub fn (mut p Plot) add_trace(trace Trace) 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 { + return p.add_trace(trace) +} + +// heatmap adds a heatmap trace to the plot +[inline] +pub fn (mut p Plot) heatmap(trace HeatmapTrace) Plot { + return p.add_trace(trace) +} + +// surface adds a surface trace to the plot +[inline] +pub fn (mut p Plot) surface(trace SurfaceTrace) Plot { + 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 - 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 + return p.add_trace(next_trace) +} + +// bar adds a bar trace to the plot +[inline] +pub fn (mut p Plot) bar(trace BarTrace) Plot { + return p.add_trace(trace) +} + +// histogram adds a histogram trace to the plot +[inline] +pub fn (mut p Plot) histogram(trace HistogramTrace) Plot { + return p.add_trace(trace) } -pub fn (mut p Plot) add_annotation(annotation Annotation) Plot { +// box adds a box trace to the plot +[inline] +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 { +// 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 if next_layout.xaxis.range.len != 2 { diff --git a/plot/plot_test.v b/plot/plot_test.v index b67b09591..e2da42fcb 100644 --- a/plot/plot_test.v +++ b/plot/plot_test.v @@ -1,14 +1,13 @@ module plot fn test_bar() { - mut plt := new_plot() + mut plt := Plot.new() - 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/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..4359a4daa 100644 --- a/plot/show.v +++ b/plot/show.v @@ -1,70 +1,93 @@ module plot import json -import os import time -import vsl.errors +import vweb -const ( - schema_version = 'v1.0.3' - venv_dir_name = '.plotvenv_${schema_version}' - data_dir_name = '.data_${schema_version}' -) +// port is the port to run the server on. If 0, it will run on the next available port. +const port = 8000 -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) - } - } +struct App { + vweb.Context + plot Plot [vweb_global] +} - 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') +type TracesWithTypeValue = Trace | string - 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) - } +pub fn (p Plot) show() ! { $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) + vweb.run(&App{ + plot: p + }, plot.port) } } -// 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) +// 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 } -fn solve_mod_path(dirs ...string) string { - return os.join_path(@VMODROOT, ...dirs) +['/'] +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()) + 'trace': TracesWithTypeValue(it) + }) + traces_with_type_json := encode(traces_with_type) + layout_json := encode(app.plot.layout) + go fn () { + time.sleep(100 * time.millisecond) + exit(0) + }() + return app.html(' + + + VSL Plot + + +
+ + + +') } 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' } + } }