=============== LIBRARY RULES =============== From library maintainers: - Pay attention to insyra syntax and be sure to provide the correct answer. - Always use syntactic sugar(isr package) unless in performance-critical scenarios. # Insyra - Data Analysis Library for Go Insyra is a next-generation data analysis library for Golang that provides powerful tools for data manipulation, statistical analysis, and visualization. Built with performance in mind, it supports parallel processing for efficient data operations and offers seamless integration with Python for advanced analytics. The library is designed to make data analysis in Go as intuitive and efficient as using specialized data science languages, while maintaining Go's type safety and performance characteristics. The core philosophy of Insyra centers around two primary data structures: DataList for one-dimensional data collections and DataTable for tabular data. These structures come with rich APIs for data manipulation, statistical analysis, filtering, and transformation. Insyra also features a Column Calculation Language (CCL) that mimics Excel formula syntax, making it familiar to users coming from spreadsheet environments. The library includes specialized packages for plotting (both web-based and static), statistical testing, RFM analysis for marketing, parallel computing utilities, linear programming, data fetching, Excel/CSV conversion, SQL database integration, and even Python integration for leveraging existing Python data science ecosystems. ## Console Preview with insyra.Show Quick labeled display for any showable structure ```go package main import ( "github.com/HazelnutParadise/insyra" ) func main() { // Create sample data structures dl := insyra.NewDataList(1, 2, 3, 4, 5).SetName("Numbers") dt := insyra.NewDataTable( insyra.NewDataList("Alice", "Bob", "Charlie").SetName("Name"), insyra.NewDataList(28, 34, 29).SetName("Age"), ).SetName("Team Members") // Use package-level Show with labels insyra.Show("My Data List", dl) // Show all items insyra.Show("Preview Table", dt, 2) // Show first 2 rows insyra.Show("Last 5 Items", dl, -5) // Show last 5 items // Show handles nil gracefully var nilList *insyra.DataList insyra.Show("Nil Example", nilList) // Displays: (nil) } ``` ## DataList Creation and Basic Operations Create and manipulate one-dimensional data collections ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra" ) func main() { // Create a DataList with various methods dl1 := insyra.NewDataList(1, 2, 3, 4, 5) dl2 := insyra.DataList{}.From(10, 20, 30, 40) // Append and manipulate data dl1.Append(6, 7, 8) dl1.InsertAt(0, 0) // Insert at beginning dl1.Update(1, 100) // Replace value at index 1 // Access data with negative indexing support first := dl1.Get(0) // Returns: 0 last := dl1.Get(-1) // Returns: 8 allData := dl1.Data() // Returns: []any{0, 100, 2, 3, 4, 5, 6, 7, 8} // Statistical operations fmt.Printf("Mean: %.2f\n", dl1.Mean()) fmt.Printf("Median: %.2f\n", dl1.Median()) fmt.Printf("StdDev: %.2f\n", dl1.Std()) fmt.Printf("Length: %d\n", dl1.Len()) // Naming for better organization dl2.SetName("Sales_Data") fmt.Println("Name:", dl2.Name()) } ``` ## DataList Filtering and Transformation Filter, map, and transform data collections ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra" ) func main() { scores := insyra.NewDataList(45, 67, 89, 92, 55, 78, 34, 88) // Filter data based on conditions passing := scores.FilterByCondition(func(v any) bool { return v.(int) >= 60 }) fmt.Println("Passing scores:", passing.Data()) // [67, 89, 92, 78, 88] // Map transformation doubled := scores.Map(func(v any) any { return v.(int) * 2 }) fmt.Println("Doubled:", doubled.Data()) // [90, 134, 178, 184, 110, 156, 68, 176] // Find values firstHigh := scores.FindFirst(89) // Returns: 2 (index) allHighScores := scores.FindAll(88) // Returns: []any{7} // Count occurrences count := scores.Count(67) // Returns: 1 counter := scores.Counter() // Returns: map[any]int with all counts // Remove duplicates and sort unique := scores.Unique() sorted := scores.Sort() // Ascending descending := scores.Sort(true) // Descending fmt.Printf("Unique values: %v\n", unique.Data()) fmt.Printf("Sorted ascending: %v\n", sorted.Data()) } ``` ## DataTable Creation and CSV Operations Load, create, and export tabular data ```go package main import ( "log" "github.com/HazelnutParadise/insyra" ) func main() { // Create DataTable from columns names := insyra.NewDataList("Alice", "Bob", "Charlie", "David").SetName("Name") ages := insyra.NewDataList(28, 34, 29, 42).SetName("Age") salaries := insyra.NewDataList(65000, 75000, 68000, 82000).SetName("Salary") dt := insyra.NewDataTable(names, ages, salaries) dt.SetName("Employee_Data") // Display the table dt.Show() // Read from CSV file csvData, err := insyra.ReadCSV_File("employees.csv", false, true) if err != nil { log.Fatal(err) } csvData.Show() // Read from CSV string csvString := `name,age,city John,30,NYC Jane,25,LA Bob,35,Chicago` dtFromString, err := insyra.ReadCSV_String(csvString, false, true) if err != nil { log.Fatal(err) } // Export to CSV err = dt.ToCSV("output.csv", true, true, true) // Include row names, column names, and BOM if err != nil { log.Fatal(err) } // Get table dimensions rows, cols := dt.Size() log.Printf("Table size: %d rows × %d columns\n", rows, cols) } ``` ## DataTable JSON Operations Read and write JSON format data ```go package main import ( "log" "github.com/HazelnutParadise/insyra" ) func main() { // Create a sample DataTable names := insyra.NewDataList("Alice", "Bob", "Charlie").SetName("name") ages := insyra.NewDataList(28, 34, 29).SetName("age") scores := insyra.NewDataList(95.5, 87.3, 91.8).SetName("score") dt := insyra.NewDataTable(names, ages, scores) // Export to JSON file err := dt.ToJSON("data.json", true) // Use column names as keys if err != nil { log.Fatal(err) } // Convert to JSON string jsonStr := dt.ToJSON_String(true) log.Println("JSON output:", jsonStr) // Convert to JSON bytes jsonBytes := dt.ToJSON_Bytes(true) log.Printf("JSON bytes length: %d\n", len(jsonBytes)) // Read from JSON file dtFromJSON, err := insyra.ReadJSON_File("data.json") if err != nil { log.Fatal(err) } dtFromJSON.Show() // Read from JSON data (bytes, string, or other formats) dtFromBytes, err := insyra.ReadJSON(jsonBytes) if err != nil { log.Fatal(err) } dtFromBytes.Show() } ``` ## DataTable SQL Operations Read from and write to SQL databases using GORM ```go package main import ( "log" "github.com/HazelnutParadise/insyra" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func main() { // Initialize database connection db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) if err != nil { log.Fatal(err) } // Create a sample DataTable names := insyra.NewDataList("Alice", "Bob", "Charlie").SetName("name") ages := insyra.NewDataList(28, 34, 29).SetName("age") salaries := insyra.NewDataList(75000, 85000, 70000).SetName("salary") dt := insyra.NewDataTable(names, ages, salaries) // Write to SQL database options := insyra.ToSQLOptions{ IfExists: insyra.ReplaceIfExists, // Replace table if exists RowNames: false, } err = dt.ToSQL(db, "employees", options) if err != nil { log.Fatal(err) } // Read from SQL database readOpts := insyra.ReadSQLOptions{ WhereClause: "age > 28", OrderBy: "salary DESC", Limit: 10, Offset: 0, } dtFromSQL, err := insyra.ReadSQL(db, "employees", readOpts) if err != nil { log.Fatal(err) } dtFromSQL.Show() // Read with custom query customOpts := insyra.ReadSQLOptions{ Query: "SELECT name, age FROM employees WHERE salary > ?", } dtCustom, err := insyra.ReadSQL(db, "", customOpts, 70000) if err != nil { log.Fatal(err) } dtCustom.Show() } ``` ## DataTable Row and Column Operations Add, update, and manipulate table structure ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra" ) func main() { dt := insyra.NewDataTable() // Append rows by column names dt.AppendRowsByColName( map[string]any{"name": "Alice", "age": 28, "score": 95.5}, map[string]any{"name": "Bob", "age": 34, "score": 87.3}, map[string]any{"name": "Charlie", "age": 29, "score": 91.8}, ) // Append rows by column index (A, B, C...) dt.AppendRowsByColIndex( map[string]any{"A": "David", "B": 42, "C": 88.9}, ) // Add row from DataList newRow := insyra.NewDataList("Eve", 31, 93.2).SetName("Employee_5") dt.AppendRowsFromDataList(newRow) // Access columns nameCol := dt.GetCol("A") // By index ageCol := dt.GetColByName("age") // By name scoreCol := dt.GetColByNumber(2) // By number (0-based) fmt.Println("Names:", nameCol.Data()) // Access individual elements element := dt.GetElement(0, "B") // Row 0, Column B elementByNum := dt.GetElementByNumberIndex(1, 2) // Row 1, Column 2 // Update elements dt.UpdateElement(0, "C", 98.5) dt.UpdateElementByNumberIndex(1, 1, 35) // Get row row := dt.GetRow(0) fmt.Println("First row:", row.Data()) // Set row and column names dt.SetRowNameByIndex(0, "Best_Employee") dt.SetColNameByNumber(0, "Full_Name") dt.ShowRange(3) // Show first 3 rows } ``` ## Column Calculation Language (CCL) Excel-like formula language for column calculations ```go package main import ( "github.com/HazelnutParadise/insyra" ) func main() { // Create a table with numeric data dt := insyra.NewDataTable() dt.AppendRowsByColName( map[string]any{"math": 85, "english": 78, "science": 92}, map[string]any{"math": 92, "english": 88, "science": 95}, map[string]any{"math": 78, "english": 65, "science": 82}, map[string]any{"math": 95, "english": 91, "science": 88}, ) // Basic arithmetic with CCL (columns are A, B, C...) dt.AddColUsingCCL("total", "A + B + C") dt.AddColUsingCCL("average", "(A + B + C) / 3") // Conditional logic with IF dt.AddColUsingCCL("grade", "IF(average >= 90, 'A', IF(average >= 80, 'B', IF(average >= 70, 'C', 'F')))") // Chained comparisons (range checks) dt.AddColUsingCCL("pass_status", "IF(average >= 60, 'Pass', 'Fail')") dt.AddColUsingCCL("in_range", "IF(80 <= average <= 95, 'Target Range', 'Outside Range')") // Logical operators dt.AddColUsingCCL("honors", "IF(AND(A >= 85, B >= 85, C >= 85), 'Yes', 'No')") dt.AddColUsingCCL("needs_help", "IF(OR(A < 70, B < 70, C < 70), 'Yes', 'No')") // CASE for multiple conditions dt.AddColUsingCCL("performance", "CASE(average >= 90, 'Excellent', average >= 80, 'Good', average >= 70, 'Satisfactory', 'Needs Improvement')") // String concatenation dt.AddColUsingCCL("report", "CONCAT(grade, ' - ', performance)") // Mathematical operations dt.AddColUsingCCL("math_squared", "A ^ 2") dt.AddColUsingCCL("weighted_avg", "(A * 0.4) + (B * 0.3) + (C * 0.3)") dt.Show() } ``` ## DataTable Filtering and Searching Filter rows and search for specific values ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra" ) func main() { // Create sample employee data dt := insyra.NewDataTable() dt.AppendRowsByColName( map[string]any{"name": "Alice", "dept": "Engineering", "salary": 75000, "years": 3}, map[string]any{"name": "Bob", "dept": "Sales", "salary": 65000, "years": 5}, map[string]any{"name": "Charlie", "dept": "Engineering", "salary": 85000, "years": 7}, map[string]any{"name": "David", "dept": "Marketing", "salary": 70000, "years": 4}, map[string]any{"name": "Eve", "dept": "Engineering", "salary": 90000, "years": 8}, ) // Filter by column value engineers := dt.FilterByColValue("dept", "Engineering") fmt.Println("Engineers:") engineers.Show() // Filter by custom condition seniorHighEarners := dt.FilterRows(func(row []any) bool { years := row[3].(int) salary := row[2].(int) return years >= 5 && salary >= 75000 }) fmt.Println("\nSenior high earners:") seniorHighEarners.Show() // Search in column found := dt.SearchInCol("B", "Engineering") fmt.Printf("\n'Engineering' found at rows: %v\n", found) // Search across all columns foundAll := dt.Search("Alice") fmt.Printf("'Alice' found at: %v\n", foundAll) // Get unique values in a column departments := dt.GetCol("B").Unique() fmt.Println("\nUnique departments:", departments.Data()) // Sort table by column sortedBySalary := dt.SortBy("C", false) // Descending fmt.Println("\nSorted by salary (descending):") sortedBySalary.Show() } ``` ## Statistical Analysis with stats Package Perform correlation analysis and hypothesis testing ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra" "github.com/HazelnutParadise/insyra/stats" ) func main() { // Create sample data height := insyra.NewDataList(160, 165, 170, 175, 180, 185).SetName("Height") weight := insyra.NewDataList(55, 60, 68, 75, 82, 88).SetName("Weight") age := insyra.NewDataList(25, 28, 30, 35, 40, 45).SetName("Age") dt := insyra.NewDataTable(height, weight, age) // Correlation analysis corrMatrix, pMatrix, chiSquare, pValue, df := stats.CorrelationAnalysis( dt, stats.PearsonCorrelation, ) fmt.Println("Correlation Matrix:") corrMatrix.Show() fmt.Println("\nP-Value Matrix:") pMatrix.Show() fmt.Printf("\nBartlett's Test - Chi-Square: %.4f, P-Value: %.4f, DF: %d\n", chiSquare, pValue, df) // Simple correlation between two variables corrResult := stats.Correlation(height, weight, stats.PearsonCorrelation) fmt.Printf("\nHeight-Weight Correlation: %.4f (p=%.4f)\n", corrResult.Statistic, corrResult.PValue) // T-test group1 := insyra.NewDataList(23, 25, 27, 29, 31) group2 := insyra.NewDataList(30, 32, 35, 37, 39) tResult := stats.TwoSampleTTest(group1, group2, true) fmt.Printf("\nT-Test Results:\n") fmt.Printf(" T-Statistic: %.4f\n", tResult.Statistic) fmt.Printf(" P-Value: %.4f\n", tResult.PValue) // Descriptive statistics fmt.Printf("\nDescriptive Statistics for Height:\n") fmt.Printf(" Mean: %.2f\n", height.Mean()) fmt.Printf(" Median: %.2f\n", height.Median()) fmt.Printf(" Std Dev: %.2f\n", height.Std()) fmt.Printf(" Variance: %.2f\n", height.Variance()) fmt.Printf(" Min: %.2f, Max: %.2f\n", height.Min(), height.Max()) } ``` ## Parallel Processing with parallel Package Execute functions concurrently and collect results ```go package main import ( "fmt" "time" "github.com/HazelnutParadise/insyra/parallel" ) func main() { // Define functions to run in parallel func1 := func() (string, int) { time.Sleep(100 * time.Millisecond) return "Result from function 1", 42 } func2 := func() (string, float64) { time.Sleep(150 * time.Millisecond) return "Result from function 2", 3.14 } func3 := func() string { time.Sleep(50 * time.Millisecond) return "Result from function 3" } // Run functions in parallel and wait for results results := parallel.GroupUp(func1, func2, func3).Run().AwaitResult() fmt.Println("All functions completed!") for i, result := range results { fmt.Printf("Function %d returned: %v\n", i+1, result) } // For functions without return values task1 := func() { fmt.Println("Task 1 executing...") time.Sleep(100 * time.Millisecond) } task2 := func() { fmt.Println("Task 2 executing...") time.Sleep(100 * time.Millisecond) } task3 := func() { fmt.Println("Task 3 executing...") time.Sleep(100 * time.Millisecond) } // Run and wait without collecting results (more efficient) parallel.GroupUp(task1, task2, task3).Run().AwaitNoResult() fmt.Println("All tasks completed!") } ``` ## RFM Analysis with mkt Package Marketing analytics for customer segmentation ```go package main import ( "fmt" "log" "github.com/HazelnutParadise/insyra" "github.com/HazelnutParadise/insyra/mkt" ) func main() { // Load transaction data csvData := `customer_id,transaction_date,amount CUST001,2024-01-15,250.50 CUST002,2024-01-20,180.00 CUST001,2024-02-10,320.75 CUST003,2024-02-15,450.00 CUST002,2024-03-05,200.00 CUST001,2024-03-20,290.50 CUST003,2024-03-25,520.00 CUST004,2024-01-10,150.00` dt, err := insyra.ReadCSV_String(csvData, false, true) if err != nil { log.Fatal(err) } // Configure RFM analysis config := mkt.RFMConfig{ CustomerIDColName: "customer_id", TradingDayColName: "transaction_date", AmountColName: "amount", NumGroups: 5, // Divide into 5 groups (quintiles) DateFormat: "YYYY-MM-DD", TimeScale: mkt.TimeScaleDaily, } // Perform RFM analysis rfmResult := mkt.RFM(dt, config) if rfmResult != nil { fmt.Println("RFM Analysis Results:") rfmResult.Show() // The result table contains: // - Customer ID // - R Score (Recency: 1-5, where 5 is most recent) // - F Score (Frequency: 1-5, where 5 is most frequent) // - M Score (Monetary: 1-5, where 5 is highest spending) // - RFM Score (combined: e.g., "555" for best customers) // Filter for best customers (RFM = 555 or 554, etc.) bestCustomers := rfmResult.FilterByColValue("rfm_score", "555") fmt.Println("\nBest Customers (RFM = 555):") bestCustomers.Show() // Save results err = rfmResult.ToCSV("rfm_analysis_results.csv", true, true, true) if err != nil { log.Fatal(err) } } } ``` ## Data Visualization with plot Package Create interactive charts and save as HTML or PNG ```go package main import ( "log" "github.com/HazelnutParadise/insyra" "github.com/HazelnutParadise/insyra/plot" ) func main() { // Prepare data using DataList months := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun"} productA := insyra.NewDataList(120, 200, 150, 180, 220, 250).SetName("Product A") productB := insyra.NewDataList(80, 160, 90, 140, 170, 200).SetName("Product B") productC := insyra.NewDataList(200, 180, 220, 240, 260, 280).SetName("Product C") // Create bar chart barConfig := plot.BarChartConfig{ Title: "Sales Performance", Subtitle: "First Half of 2024", XAxis: months, Data: []*insyra.DataList{productA, productB, productC}, XAxisName: "Month", YAxisName: "Sales (units)", ShowLabels: true, Colors: []string{"#5470C6", "#91CC75", "#EE6666"}, GridTop: "100", } barChart := plot.CreateBarChart(barConfig) // Save as HTML (interactive) err := plot.SaveHTML(barChart, "sales_bar_chart.html") if err != nil { log.Fatal(err) } // Save as PNG (static image) err = plot.SavePNG(barChart, "sales_bar_chart.png") if err != nil { log.Fatal(err) } // Create line chart lineConfig := plot.LineChartConfig{ Title: "Revenue Trend", Subtitle: "Monthly Revenue Analysis", XAxis: months, Data: []*insyra.DataList{productA, productB, productC}, XAxisName: "Month", YAxisName: "Revenue ($1000s)", Smooth: true, // Smooth line curves Colors: []string{"#5470C6", "#91CC75", "#EE6666"}, } lineChart := plot.CreateLineChart(lineConfig) plot.SaveHTML(lineChart, "revenue_line_chart.html") fmt.Println("Charts created successfully!") } ``` ## Advanced Visualizations with plot Package Create specialized charts for various analysis needs ```go package main import ( "github.com/HazelnutParadise/insyra" "github.com/HazelnutParadise/insyra/plot" ) func main() { // Box Plot for distribution analysis boxConfig := plot.BoxPlotConfig{ Title: "Score Distribution by Subject", XAxis: []string{"Math", "English", "Science"}, Data: map[string][][]float64{ "Class A": { {75, 80, 85, 90, 95}, {70, 75, 80, 85, 90}, {80, 85, 90, 95, 100}, }, }, } boxChart := plot.CreateBoxPlot(boxConfig) plot.SaveHTML(boxChart, "box_plot.html") // Gauge Chart for KPI visualization gaugeConfig := plot.GaugeChartConfig{ Title: "Sales Target Achievement", SeriesName: "Q1 Sales", Value: 75.5, } gaugeChart := plot.CreateGaugeChart(gaugeConfig) plot.SaveHTML(gaugeChart, "gauge_chart.html") // Funnel Chart for conversion analysis funnelConfig := plot.FunnelChartConfig{ Title: "Sales Funnel", SeriesName: "Conversion", Data: map[string]float64{ "Visitors": 10000, "Signups": 5000, "Trials": 2000, "Purchases": 500, }, ShowLabels: true, } funnelChart := plot.CreateFunnelChart(funnelConfig) plot.SaveHTML(funnelChart, "funnel_chart.html") // K-line Chart for financial data klineConfig := plot.KlineChartConfig{ Title: "Stock Price", DataZoom: true, Data: map[string][4]float32{ "2024-01-01": {100, 110, 95, 105}, // Open, Close, Low, High "2024-01-02": {105, 115, 100, 112}, "2024-01-03": {112, 108, 102, 118}, }, } klineChart := plot.CreateKlineChart(klineConfig) plot.SaveHTML(klineChart, "kline_chart.html") // Radar Chart for multi-dimensional comparison radarConfig := plot.RadarChartConfig{ Title: "Product Comparison", Data: map[string]map[string]float32{ "Product A": {"Quality": 90, "Price": 70, "Service": 85, "Design": 95}, "Product B": {"Quality": 85, "Price": 90, "Service": 80, "Design": 75}, }, } radarChart := plot.CreateRadarChart(radarConfig) plot.SaveHTML(radarChart, "radar_chart.html") // Liquid Chart for percentage visualization liquidConfig := plot.LiquidChartConfig{ Title: "Goal Completion", Data: map[string]float32{"Progress": 0.68}, ShowLabels: true, IsWaveAnimation: true, Shape: "circle", } liquidChart := plot.CreateLiquidChart(liquidConfig) plot.SaveHTML(liquidChart, "liquid_chart.html") // Pie Chart for proportional data pieConfig := plot.PieChartConfig{ Title: "Market Share", Subtitle: "By Product Category", Labels: []string{"Electronics", "Clothing", "Food", "Books"}, Data: []float64{40.5, 25.3, 18.7, 15.5}, ShowLabels: true, ShowPercent: true, RoseType: "radius", // Optional: use rose chart style } pieChart := plot.CreatePieChart(pieConfig) plot.SaveHTML(pieChart, "pie_chart.html") // Scatter Chart for correlation visualization scatterConfig := plot.ScatterChartConfig{ Title: "Height vs Weight Correlation", Subtitle: "Sample Population", Data: map[string][][]float64{ "Group A": {{160, 55}, {165, 60}, {170, 68}, {175, 75}}, "Group B": {{162, 58}, {168, 65}, {172, 70}, {178, 80}}, }, XAxisName: "Height (cm)", YAxisName: "Weight (kg)", ShowLabels: true, SymbolSize: 15, } scatterChart := plot.CreateScatterChart(scatterConfig) plot.SaveHTML(scatterChart, "scatter_chart.html") // Heatmap for matrix data visualization heatmapConfig := plot.HeatmapChartConfig{ Title: "Sales Heatmap", Subtitle: "By Region and Month", XAxis: []string{"Jan", "Feb", "Mar", "Apr", "May"}, YAxis: []string{"North", "South", "East", "West"}, Data: [][3]int{{0, 0, 5}, {0, 1, 1}, {0, 2, 3}, {1, 0, 2}, {1, 1, 4}}, Min: 0, Max: 10, } heatmapChart := plot.CreateHeatmapChart(heatmapConfig) plot.SaveHTML(heatmapChart, "heatmap_chart.html") // Sankey Diagram for flow visualization sankeyConfig := plot.SankeyChartConfig{ Title: "Energy Flow", Subtitle: "Production to Consumption", Nodes: []string{"Coal", "Natural Gas", "Solar", "Electricity", "Heat", "Industry", "Residential"}, Links: []plot.SankeyLink{ {Source: "Coal", Target: "Electricity", Value: 40}, {Source: "Natural Gas", Target: "Electricity", Value: 30}, {Source: "Solar", Target: "Electricity", Value: 15}, {Source: "Electricity", Target: "Industry", Value: 50}, {Source: "Electricity", Target: "Residential", Value: 35}, }, Curveness: 0.5, ShowLabels: true, } sankeyChart := plot.CreateSankeyChart(sankeyConfig) plot.SaveHTML(sankeyChart, "sankey_chart.html") // ThemeRiver Chart for temporal stacked data themeRiverConfig := plot.ThemeRiverChartConfig{ Title: "Website Traffic", Subtitle: "By Source Over Time", Data: []plot.ThemeRiverData{ {Date: "2024/01/01", Value: 120, Name: "Direct"}, {Date: "2024/01/01", Value: 80, Name: "Organic"}, {Date: "2024/01/02", Value: 150, Name: "Direct"}, {Date: "2024/01/02", Value: 95, Name: "Organic"}, }, } themeRiverChart := plot.CreateThemeRiverChart(themeRiverConfig) plot.SaveHTML(themeRiverChart, "themeriver_chart.html") // Word Cloud for text frequency visualization wordCloudConfig := plot.WordCloudConfig{ Title: "Popular Keywords", Subtitle: "From Customer Feedback", Data: map[string]float32{ "quality": 80, "service": 70, "fast": 65, "excellent": 60, "helpful": 55, "professional": 50, "responsive": 45, "friendly": 40, }, Shape: "circle", SizeRange: []float32{14, 80}, } wordCloud := plot.CreateWordCloud(wordCloudConfig) plot.SaveHTML(wordCloud, "wordcloud.html") } ``` ## Static Visualization with gplot Package Create static charts with no Chrome dependency ```go package main import ( "log" "math" "github.com/HazelnutParadise/insyra" "github.com/HazelnutParadise/insyra/gplot" ) func main() { // Create bar chart with error bars measurements := []float64{5.2, 7.8, 6.4, 9.1, 8.5, 7.2} uncertainties := []float64{0.5, 0.8, 0.6, 0.9, 0.7, 0.6} barConfig := gplot.BarChartConfig{ Title: "Experimental Measurements", XAxis: []string{"Trial 1", "Trial 2", "Trial 3", "Trial 4", "Trial 5", "Trial 6"}, Data: measurements, XAxisName: "Trial Number", YAxisName: "Measured Value (units)", ErrorBars: uncertainties, BarWidth: 30, } barPlot := gplot.CreateBarChart(barConfig) gplot.SaveChart(barPlot, "measurements_bar.png") // Create line chart xAxis := []string{"Week 1", "Week 2", "Week 3", "Week 4", "Week 5"} seriesA := insyra.NewDataList(120.0, 200.0, 150.0, 180.0, 220.0).SetName("Series A") seriesB := insyra.NewDataList(80.0, 160.0, 90.0, 140.0, 170.0).SetName("Series B") lineConfig := gplot.LineChartConfig{ Title: "Weekly Metrics", XAxis: xAxis, Data: []*insyra.DataList{seriesA, seriesB}, XAxisName: "Week", YAxisName: "Value", } linePlot := gplot.CreateLineChart(lineConfig) gplot.SaveChart(linePlot, "metrics_line.png") // Create scatter plot scatterConfig := gplot.ScatterPlotConfig{ Title: "Correlation Analysis", Data: map[string][][]float64{ "Dataset 1": {{1, 2}, {2, 4}, {3, 6}, {4, 8}}, "Dataset 2": {{1, 3}, {2, 5}, {3, 7}, {4, 9}}, }, XAxisName: "X Variable", YAxisName: "Y Variable", } scatterPlot := gplot.CreateScatterPlot(scatterConfig) gplot.SaveChart(scatterPlot, "scatter.png") // Create step chart stepConfig := gplot.StepChartConfig{ Title: "Step Function", XAxis: []float64{0, 1, 2, 3, 4, 5}, Data: map[string][]float64{"Signal": {0, 1, 1, 2, 2, 3}}, StepStyle: "post", } stepPlot := gplot.CreateStepChart(stepConfig) gplot.SaveChart(stepPlot, "step.png") // Create histogram histConfig := gplot.HistogramConfig{ Title: "Data Distribution", Data: []float64{1.2, 2.3, 1.8, 3.4, 2.1, 1.9, 2.8, 3.1, 2.5, 1.7}, Bins: 5, XAxisName: "Value", YAxisName: "Frequency", } histPlot := gplot.CreateHistogram(histConfig) gplot.SaveChart(histPlot, "histogram.png") // Create heatmap heatmapConfig := gplot.HeatmapChartConfig{ Title: "Correlation Heatmap", Data: [][]float64{ {1.0, 0.8, 0.6}, {0.8, 1.0, 0.7}, {0.6, 0.7, 1.0}, }, XAxisName: "Variables", YAxisName: "Variables", } heatmapPlot := gplot.CreateHeatmapChart(heatmapConfig) gplot.SaveChart(heatmapPlot, "heatmap.png") // Create function plot funcConfig := gplot.FunctionPlotConfig{ Title: "Mathematical Function", XAxis: "X", YAxis: "Y", Func: func(x float64) float64 { return math.Sin(x) * math.Exp(-x/10) }, XMin: 0, XMax: 20, } funcPlot := gplot.CreateFunctionPlot(funcConfig) gplot.SaveChart(funcPlot, "function.png") log.Println("Static charts created successfully!") } ``` ## Excel and CSV Conversion with csvxl Package Convert between CSV and Excel formats with automatic encoding detection ```go package main import ( "log" "github.com/HazelnutParadise/insyra/csvxl" ) func main() { // Convert multiple CSV files to Excel (auto-detect encoding) csvFiles := []string{"sales.csv", "inventory.csv", "customers.csv"} sheetNames := []string{"Sales", "Inventory", "Customers"} csvxl.CsvToExcel(csvFiles, sheetNames, "business_data.xlsx") // Detect encoding of a CSV file encoding, err := csvxl.DetectEncoding("myfile.csv") if err != nil { log.Fatal(err) } log.Printf("Detected encoding: %s\n", encoding) // Append CSV to existing Excel file newCSVs := []string{"new_sales.csv", "new_customers.csv"} newSheets := []string{"Q2_Sales", "New_Customers"} csvxl.AppendCsvToExcel(newCSVs, newSheets, "business_data.xlsx") // Split Excel file into multiple CSV files csvxl.ExcelToCsv("business_data.xlsx", "csv_output", nil) // Convert all CSV files in a directory to one Excel file csvxl.EachCsvToOneExcel("data_folder", "combined.xlsx") // Split all Excel files in a directory to CSV files csvxl.EachExcelToCsv("excel_folder", "csv_output") log.Println("Conversion completed successfully!") } ``` ## Data Fetching with datafetch Package Fetch data from external sources like Google Maps ```go package main import ( "fmt" "log" "github.com/HazelnutParadise/insyra/datafetch" ) func main() { // Initialize Google Maps crawler crawler := datafetch.GoogleMapsStores() if crawler == nil { log.Fatal("Failed to initialize Google Maps crawler") } // Search for stores stores := crawler.Search("Starbucks") fmt.Printf("Found %d stores\n", len(stores)) if len(stores) > 0 { // Get the first store store := stores[0] fmt.Printf("Store: %s (ID: %s)\n", store.Name, store.ID) // Fetch reviews with options options := datafetch.GoogleMapsStoreReviewsFetchingOptions{ SortBy: datafetch.SortByNewest, MaxWaitingInterval: 3000, } reviews := crawler.GetReviews(store.ID, 10, options) if reviews != nil { fmt.Printf("Fetched %d reviews\n", len(reviews)) // Convert to DataTable for analysis dt := reviews.ToDataTable() if dt != nil { dt.Show() // Save to CSV err := dt.ToCSV("reviews.csv", true, true, true) if err != nil { log.Fatal(err) } } } } // Chained approach dt := crawler.GetReviews(crawler.Search("Din Tai Fung")[0].ID, 5).ToDataTable() if dt != nil { dt.Show() } } ``` ## Linear Programming with lpgen and lp Packages Generate and solve linear programming models ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra/lpgen" "github.com/HazelnutParadise/insyra/lp" ) func main() { // Create a linear programming model model := lpgen.NewLPModel() // Set objective function to maximize model.SetObjective("Maximize", "3 x1 + 4 x2 + 2 x3") // Add constraints model.AddConstraint("2 x1 + 3 x2 + x3 <= 100") model.AddConstraint("4 x1 + 2 x2 + 3 x3 <= 120") model.AddConstraint("x1 + x2 + x3 <= 50") // Add variable bounds model.AddBound("0 <= x1 <= 20") model.AddBound("0 <= x2 <= 30") model.AddBound("0 <= x3 <= 25") // Add integer variables model.AddIntegerVar("x1") model.AddIntegerVar("x2") // Generate LP file model.GenerateLPFile("optimization_model.lp") // Solve using GLPK (requires GLPK installation) solution := lp.SolveLP("optimization_model.lp") if solution != nil { fmt.Println("Optimal solution found!") solution.Show() } // Parse LINGO model (if you have LINGO output) lingoModel := lpgen.ParseLingoModel_txt("lingo_output.txt") lingoModel.GenerateLPFile("from_lingo.lp") } ``` ## Syntactic Sugar with isr Package Simplified API for common operations ```go package main import ( "fmt" "github.com/HazelnutParadise/insyra/isr" ) func main() { // Create DataList with syntactic sugar // Use Of (alias for From) - both work the same way dl := isr.DL.Of(1, 2, 3, 4, 5) // Chainable operations dl.Push(6, 7, 8) // Append values value := dl.At(0) // Get value at index fmt.Println("Data:", dl.Data()) fmt.Printf("First element: %v\n", value) // Create DataTable with syntactic sugar dt := isr.DT.From(isr.DLs{ isr.DL.Of("Alice", "Bob", "Charlie").Name("employee"), isr.DL.Of(28, 34, 29).Name("age"), isr.DL.Of(75000, 85000, 70000).Name("salary"), }) dt.Name("Employee_Records") dt.Show() // Quick CSV operations csvData := `name,score,grade Alice,95,A Bob,87,B Charlie,92,A` table, err := isr.ReadCSVString(csvData, false, true) if err != nil { panic(err) } table.Show() // Save to CSV err = isr.SaveCSV(table, "output.csv", true, true) if err != nil { panic(err) } // JSON operations err = isr.SaveJSON(table, "output.json") if err != nil { panic(err) } fmt.Println("Operations completed successfully!") } ``` ## Thread-Safe Operations with AtomicDo Concurrent access to DataList and DataTable ```go package main import ( "fmt" "sync" "github.com/HazelnutParadise/insyra" ) func main() { // AtomicDo ensures thread-safe operations dl := insyra.NewDataList() // Multiple goroutines appending concurrently var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func(value int) { defer wg.Done() dl.AtomicDo(func(dl *insyra.DataList) { dl.Append(value) }) }(i) } wg.Wait() fmt.Printf("DataList length after concurrent appends: %d\n", dl.Len()) // DataTable with concurrent updates dt := insyra.NewDataTable() dt.AppendRowsByColName( map[string]any{"id": 1, "value": 100}, map[string]any{"id": 2, "value": 200}, map[string]any{"id": 3, "value": 300}, ) // Concurrent updates to different rows for i := 0; i < 3; i++ { wg.Add(1) go func(rowIndex int) { defer wg.Done() dt.AtomicDo(func(dt *insyra.DataTable) { // Multi-step consistent operation current := dt.GetElement(rowIndex, "B").(int) dt.UpdateElement(rowIndex, "B", current*2) }) }(i) } wg.Wait() fmt.Println("DataTable after concurrent updates:") dt.Show() // AtomicDo is reentrant - can be nested dt.AtomicDo(func(dt *insyra.DataTable) { rows, cols := dt.Size() fmt.Printf("Table size: %d × %d\n", rows, cols) // Nested AtomicDo call works without deadlock col := dt.GetCol("A") col.AtomicDo(func(col *insyra.DataList) { fmt.Printf("Column length: %d\n", col.Len()) }) }) } ``` ## Insyra is designed for data scientists and engineers who need to perform complex data analysis tasks in Go with minimal boilerplate code. The library provides intuitive APIs for data manipulation, powerful statistical functions through the stats package, and rich visualization capabilities via both the plot package (interactive web-based charts including bar, line, box plot, gauge, funnel, K-line, radar, liquid, pie, scatter, heatmap, sankey, themeriver, and wordcloud charts) and gplot package (static charts with no dependencies including bar, line, scatter, step, histogram, heatmap, and function plots). The Column Calculation Language (CCL) enables Excel-like formula expressions, making it easy to perform calculations on tabular data without writing verbose code. Thread-safety is built in through the AtomicDo pattern, allowing safe concurrent access to data structures. Specialized packages like mkt for RFM analysis, parallel for concurrent computing, lpgen and lp for linear programming, csvxl for Excel/CSV conversion with automatic encoding detection, and datafetch for retrieving data from external sources make Insyra suitable for production-grade data pipelines. SQL database integration is provided through ReadSQL and ToSQL methods using GORM, supporting MySQL, PostgreSQL, and SQLite with flexible query options. Integration patterns vary depending on use case. For ETL pipelines, use ReadCSV_File/ReadCSV_String/ReadJSON_File/ReadJSON/ReadSQL to load data, apply transformations using CCL or filtering methods, perform statistical analysis with the stats package, and export results with ToCSV, ToJSON, ToSQL, or Excel format via csvxl. For web applications, create DataTables from API responses, apply business logic transformations, generate visualizations with the plot or gplot packages, and serve the results. For machine learning preprocessing, use DataList and DataTable for feature engineering, apply statistical transformations, handle missing values with interpolation methods, and normalize data before feeding to models. The library supports SQL integration through ReadSQL/ToSQL for database connectivity, Python integration via the py package for leveraging existing ML models, and parallel processing for computationally intensive operations. External data can be fetched using the datafetch package for sources like Google Maps reviews. Optimization problems can be modeled and solved using lpgen to generate LP files and lp to solve them with GLPK. All components are designed to work seamlessly together while maintaining Go's performance characteristics and type safety.