Explorar o código

update ts api ref (#3567)

* update ts api ref

* update

* update
zhang-prog hai 8 meses
pai
achega
fb8a8514e8

+ 109 - 106
docs/pipeline_usage/tutorials/time_series_pipelines/time_series_anomaly_detection.en.md

@@ -386,6 +386,11 @@ Below are the API references for basic service-based deployment and examples of
 </thead>
 <tbody>
 <tr>
+<td><code>image</code></td>
+<td><code>string</code> | <code>null</code></td>
+<td>The image of time series anomaly detection result. The image is in JPEG format and encoded in Base64.</td>
+</tr>
+<tr>
 <td><code>csv</code></td>
 <td><code>string</code></td>
 <td>The result of time-series anomaly detection in CSV format. Encoded in UTF-8+Base64.</td>
@@ -394,7 +399,8 @@ Below are the API references for basic service-based deployment and examples of
 </table>
 <p>An example of <code>result</code> is as follows:</p>
 <pre><code class="language-json">{
-&quot;csv&quot;: &quot;xxxxxx&quot;
+"csv": "xxxxxx",
+"image": "xxxxxx"
 }
 </code></pre></details>
 
@@ -408,6 +414,7 @@ import requests
 
 API_URL = "http://localhost:8080/time-series-anomaly-detection"  # Service URL
 csv_path = "./test.csv"
+output_image_path = "./out.jpg"
 output_csv_path = "./out.csv"
 
 # Encode the local CSV file using Base64
@@ -423,6 +430,9 @@ response = requests.post(API_URL, json=payload)
 # Process the response data
 assert response.status_code == 200
 result = response.json()["result"]
+with open(output_image_path, "wb") as f:
+    f.write(base64.b64decode(result["image"]))
+print(f"Output image saved at  {output_image_path}")
 with open(output_csv_path, "wb") as f:
     f.write(base64.b64decode(result["csv"]))
 print(f"Output time-series data saved at {output_csv_path}")
@@ -438,6 +448,7 @@ print(f"Output time-series data saved at {output_csv_path}")
 int main() {
     httplib::Client client("localhost:8080");
     const std::string csvPath = "./test.csv";
+    const std::string outputImagePath = "./out.jpg";
     const std::string outputCsvPath = "./out.csv";
 
     httplib::Headers headers = {
@@ -469,8 +480,20 @@ int main() {
         auto result = jsonResponse["result"];
 
         // Save the data
+        std::string encodedImage = result["image"];
+        std::string decodedString = base64::from_base64(encodedImage);
+        std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
+        std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
+        if (outputImage.is_open()) {
+            outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
+            outputImage.close();
+            std::cout << "Output image data saved at " << outputImagePath << std::endl;
+        } else {
+            std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
+        }
+
         encodedCsv = result["csv"];
-        std::string decodedString = base64::from_base64(encodedCsv);
+        decodedString = base64::from_base64(encodedCsv);
         std::vector<unsigned char> decodedCsv(decodedString.begin(), decodedString.end());
         std::ofstream outputCsv(outputCsvPath, std::ios::binary | std::ios::out);
         if (outputCsv.is_open()) {
@@ -490,68 +513,6 @@ int main() {
 }
 </code></pre></details>
 
-<details><summary>C++</summary>
-
-<pre><code class="language-cpp">#include &lt;iostream&gt;
-#include &quot;cpp-httplib/httplib.h&quot; // <url id="cu9m7enftaebd5d06u9g" type="url" status="parsed" title="GitHub - Huiyicc/cpp-httplib: A C++ header-only HTTP/HTTPS server and client library" wc="15064">https://github.com/Huiyicc/cpp-httplib</url>
-#include &quot;nlohmann/json.hpp&quot; // <url id="cu9m7enftaebd5d06ua0" type="url" status="parsed" title="GitHub - nlohmann/json: JSON for Modern C++" wc="80311">https://github.com/nlohmann/json</url>
-#include &quot;base64.hpp&quot; // <url id="cu9m7enftaebd5d06uag" type="url" status="parsed" title="GitHub - tobiaslocker/base64: A modern C++ base64 encoder / decoder" wc="2293">https://github.com/tobiaslocker/base64</url>
-
-int main() {
-    httplib::Client client(&quot;localhost:8080&quot;);
-    const std::string csvPath = &quot;./test.csv&quot;;
-    const std::string outputCsvPath = &quot;./out.csv&quot;;
-
-    httplib::Headers headers = {
-        {&quot;Content-Type&quot;, &quot;application/json&quot;}
-    };
-
-    // Perform Base64 encoding
-    std::ifstream file(csvPath, std::ios::binary | std::ios::ate);
-    std::streamsize size = file.tellg();
-    file.seekg(0, std::ios::beg);
-
-    std::vector&lt;char&gt; buffer(size);
-    if (!file.read(buffer.data(), size)) {
-        std::cerr &lt;&lt; &quot;Error reading file.&quot; &lt;&lt; std::endl;
-        return 1;
-    }
-    std::string bufferStr(reinterpret_cast&lt;const char*&gt;(buffer.data()), buffer.size());
-    std::string encodedCsv = base64::to_base64(bufferStr);
-
-    nlohmann::json jsonObj;
-    jsonObj[&quot;csv&quot;] = encodedCsv;
-    std::string body = jsonObj.dump();
-
-    // Call the API
-    auto response = client.Post(&quot;/time-series-anomaly-detection&quot;, headers, body, &quot;application/json&quot;);
-    // Process the response data
-    if (response &amp;&amp; response-&gt;status == 200) {
-        nlohmann::json jsonResponse = nlohmann::json::parse(response-&gt;body);
-        auto result = jsonResponse[&quot;result&quot;];
-
-        // Save the data
-        encodedCsv = result[&quot;csv&quot;];
-        std::string decodedString = base64::from_base64(encodedCsv);
-        std::vector&lt;unsigned char&gt; decodedCsv(decodedString.begin(), decodedString.end());
-        std::ofstream outputCsv(outputCsvPath, std::ios::binary | std::ios::out);
-        if (outputCsv.is_open()) {
-            outputCsv.write(reinterpret_cast&lt;char*&gt;(decodedCsv.data()), decodedCsv.size());
-            outputCsv.close();
-            std::cout &lt;&lt; &quot;Output time-series data saved at &quot; &lt;&lt; outputCsvPath &lt;&lt; std::endl;
-        } else {
-            std::cerr &lt;&lt; &quot;Unable to open file for writing: &quot; &lt;&lt; outputCsvPath &lt;&lt; std::endl;
-        }
-    } else {
-        std::cout &lt;&lt; &quot;Failed to send HTTP request.&quot; &lt;&lt; std::endl;
-        std::cout &lt;&lt; response-&gt;body &lt;&lt; std::endl;
-        return 1;
-    }
-
-    return 0;
-}
-</code></pre></details>
-
 <details><summary>Java</summary>
 
 <pre><code class="language-java">import okhttp3.*;
@@ -566,9 +527,10 @@ import java.util.Base64;
 
 public class Main {
     public static void main(String[] args) throws IOException {
-        String API_URL = &quot;http://localhost:8080/time-series-anomaly-detection&quot;;
-        String csvPath = &quot;./test.csv&quot;;
-        String outputCsvPath = &quot;./out.csv&quot;;
+        String API_URL = "http://localhost:8080/time-series-anomaly-detection";
+        String csvPath = "./test.csv";
+        String outputImagePath = "./out.jpg";
+        String outputCsvPath = "./out.csv";
 
         // Base64 encode the local CSV file
         File file = new File(csvPath);
@@ -577,11 +539,11 @@ public class Main {
 
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectNode params = objectMapper.createObjectNode();
-        params.put(&quot;csv&quot;, csvData);
+        params.put("csv", csvData);
 
         // Create an instance of OkHttpClient
         OkHttpClient client = new OkHttpClient();
-        MediaType JSON = MediaType.Companion.get(&quot;application/json; charset=utf-8&quot;);
+        MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");
         RequestBody body = RequestBody.Companion.create(params.toString(), JSON);
         Request request = new Request.Builder()
                 .url(API_URL)
@@ -593,17 +555,24 @@ public class Main {
             if (response.isSuccessful()) {
                 String responseBody = response.body().string();
                 JsonNode resultNode = objectMapper.readTree(responseBody);
-                JsonNode result = resultNode.get(&quot;result&quot;);
+                JsonNode result = resultNode.get("result");
 
                 // Save the returned data
-                String base64Csv = result.get(&quot;csv&quot;).asText();
+                String base64Image = result.get("image").asText();
+                byte[] imageBytes = Base64.getDecoder().decode(base64Image);
+                try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
+                    fos.write(imageBytes);
+                }
+                System.out.println("Output image data saved at " + outputImagePath);
+
+                String base64Csv = result.get("csv").asText();
                 byte[] csvBytes = Base64.getDecoder().decode(base64Csv);
                 try (FileOutputStream fos = new FileOutputStream(outputCsvPath)) {
                     fos.write(csvBytes);
                 }
-                System.out.println(&quot;Output time-series data saved at &quot; + outputCsvPath);
+                System.out.println("Output time-series data saved at " + outputCsvPath);
             } else {
-                System.err.println(&quot;Request failed with code: &quot; + response.code());
+                System.err.println("Request failed with code: " + response.code());
             }
         }
     }
@@ -615,45 +584,46 @@ public class Main {
 <pre><code class="language-go">package main
 
 import (
-    &quot;bytes&quot;
-    &quot;encoding/base64&quot;
-    &quot;encoding/json&quot;
-    &quot;fmt&quot;
-    &quot;io/ioutil&quot;
-    &quot;net/http&quot;
+    "bytes"
+    "encoding/base64"
+    "encoding/json"
+    "fmt"
+    "io/ioutil"
+    "net/http"
 )
 
 func main() {
-    API_URL := &quot;http://localhost:8080/time-series-anomaly-detection&quot;
-    csvPath := &quot;./test.csv&quot;;
-    outputCsvPath := &quot;./out.csv&quot;;
+    API_URL := "http://localhost:8080/time-series-anomaly-detection"
+    csvPath := "./test.csv";
+    outputImagePath := "./out.jpg";
+    outputCsvPath := "./out.csv";
 
     // Read the CSV file and encode it with Base64
     csvBytes, err := ioutil.ReadFile(csvPath)
     if err != nil {
-        fmt.Println(&quot;Error reading CSV file:&quot;, err)
+        fmt.Println("Error reading CSV file:", err)
         return
     }
     csvData := base64.StdEncoding.EncodeToString(csvBytes)
 
-    payload := map[string]string{&quot;csv&quot;: csvData} // Base64-encoded file content
+    payload := map[string]string{"csv": csvData} // Base64-encoded file content
     payloadBytes, err := json.Marshal(payload)
     if err != nil {
-        fmt.Println(&quot;Error marshaling payload:&quot;, err)
+        fmt.Println("Error marshaling payload:", err)
         return
     }
 
     // Call the API
     client := &amp;http.Client{}
-    req, err := http.NewRequest(&quot;POST&quot;, API_URL, bytes.NewBuffer(payloadBytes))
+    req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
     if err != nil {
-        fmt.Println(&quot;Error creating request:&quot;, err)
+        fmt.Println("Error creating request:", err)
         return
     }
 
     res, err := client.Do(req)
     if err != nil {
-        fmt.Println(&quot;Error sending request:&quot;, err)
+        fmt.Println("Error sending request:", err)
         return
     }
     defer res.Body.Close()
@@ -661,33 +631,47 @@ func main() {
     // Process the response data
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
-        fmt.Println(&quot;Error reading response body:&quot;, err)
+        fmt.Println("Error reading response body:", err)
         return
     }
     type Response struct {
         Result struct {
-            Csv string `json:&quot;csv&quot;`
-        } `json:&quot;result&quot;`
+            Csv string `json:"csv"`
+            Image string `json:"image"`
+        } `json:"result"`
     }
     var respData Response
     err = json.Unmarshal([]byte(string(body)), &amp;respData)
     if err != nil {
-        fmt.Println(&quot;Error unmarshaling response body:&quot;, err)
+        fmt.Println("Error unmarshaling response body:", err)
+        return
+    }
+
+    // Decode the Base64-encoded image data and save it as a file
+    outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
+    if err != nil {
+        fmt.Println("Error decoding Base64 image data:", err)
+        return
+    }
+    err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
+    if err != nil {
+        fmt.Println("Error writing image to file:", err)
         return
     }
+    fmt.Printf("Output image data saved at %s.jpg", outputImagePath)
 
     // Decode the Base64-encoded CSV data and save it as a file
     outputCsvData, err := base64.StdEncoding.DecodeString(respData.Result.Csv)
     if err != nil {
-        fmt.Println(&quot;Error decoding Base64 CSV data:&quot;, err)
+        fmt.Println("Error decoding Base64 CSV data:", err)
         return
     }
     err = ioutil.WriteFile(outputCsvPath, outputCsvData, 0644)
     if err != nil {
-        fmt.Println(&quot;Error writing CSV to file:&quot;, err)
+        fmt.Println("Error writing CSV to file:", err)
         return
     }
-    fmt.Printf(&quot;Output time-series data saved at %s.csv&quot;, outputCsvPath)
+    fmt.Printf("Output time-series data saved at %s.csv", outputCsvPath)
 }
 </code></pre></details>
 
@@ -705,6 +689,7 @@ class Program
 {
     static readonly string API_URL = "http://localhost:8080/time-series-anomaly-detection";
     static readonly string csvPath = "./test.csv";
+    static readonly string outputImagePath = "./out.jpg";
     static readonly string outputCsvPath = "./out.csv";
 
     static async Task Main(string[] args)
@@ -726,6 +711,12 @@ class Program
         string responseBody = await response.Content.ReadAsStringAsync();
         JObject jsonResponse = JObject.Parse(responseBody);
 
+        // Save the image file
+        string base64Image = jsonResponse["result"]["image"].ToString();
+        byte[] outputImageBytes = Convert.FromBase64String(base64Image);
+        File.WriteAllBytes(outputImagePath, outputImageBytes);
+        Console.WriteLine($"Output image data saved at {outputImagePath}");
+
         // Save the CSV file
         string base64Csv = jsonResponse["result"]["csv"].ToString();
         byte[] outputCsvBytes = Convert.FromBase64String(base64Csv);
@@ -741,8 +732,9 @@ class Program
 const fs = require('fs');
 
 const API_URL = 'http://localhost:8080/time-series-anomaly-detection';
-const csvPath = &quot;./test.csv&quot;;
-const outputCsvPath = &quot;./out.csv&quot;;
+const csvPath = "./test.csv";
+const outputImagePath = "./out.jpg";
+const outputCsvPath = "./out.csv";
 
 let config = {
    method: 'POST',
@@ -761,10 +753,17 @@ function encodeFileToBase64(filePath) {
 
 axios.request(config)
 .then((response) =&gt; {
-    const result = response.data[&quot;result&quot;];
+    const result = response.data["result"];
+
+    // Save the image file
+    const imageBuffer = Buffer.from(result["image"], 'base64');
+    fs.writeFile(outputImagePath, imageBuffer, (err) =&gt; {
+      if (err) throw err;
+      console.log(`Output image data saved at ${outputImagePath}`);
+    });
 
     // Save the csv file
-    const csvBuffer = Buffer.from(result[&quot;csv&quot;], 'base64');
+    const csvBuffer = Buffer.from(result["csv"], 'base64');
     fs.writeFile(outputCsvPath, csvBuffer, (err) =&gt; {
       if (err) throw err;
       console.log(`Output time-series data saved at ${outputCsvPath}`);
@@ -779,13 +778,14 @@ axios.request(config)
 
 <pre><code class="language-php">&lt;?php
 
-$API_URL = &quot;http://localhost:8080/time-series-anomaly-detection&quot;; // Service URL
-$csv_path = &quot;./test.csv&quot;;
-$output_csv_path = &quot;./out.csv&quot;;
+$API_URL = "http://localhost:8080/time-series-anomaly-detection"; // Service URL
+$csv_path = "./test.csv";
+$output_image_path = "./out.jpg";
+$output_csv_path = "./out.csv";
 
 // Base64 encode the local CSV file
 $csv_data = base64_encode(file_get_contents($csv_path));
-$payload = array(&quot;csv&quot; =&gt; $csv_data); // Base64 encoded file content
+$payload = array("csv" =&gt; $csv_data); // Base64 encoded file content
 
 // Call the API
 $ch = curl_init($API_URL);
@@ -797,10 +797,13 @@ $response = curl_exec($ch);
 curl_close($ch);
 
 // Handle the response data
-$result = json_decode($response, true)[&quot;result&quot;];
+$result = json_decode($response, true)["result"];
+
+file_put_contents($output_image_path, base64_decode($result["image"]));
+echo "Output image data saved at " . $output_image_path . "\n";
 
-file_put_contents($output_csv_path, base64_decode($result[&quot;csv&quot;]));
-echo &quot;Output time-series data saved at &quot; . $output_csv_path . &quot;\n&quot;;
+file_put_contents($output_csv_path, base64_decode($result["csv"]));
+echo "Output time-series data saved at " . $output_csv_path . "\n";
 
 ?&gt;
 </code></pre></details>

+ 141 - 76
docs/pipeline_usage/tutorials/time_series_pipelines/time_series_anomaly_detection.md

@@ -435,6 +435,11 @@ for res in output:
 </thead>
 <tbody>
 <tr>
+<td><code>image</code></td>
+<td><code>string</code> | <code>null</code></td>
+<td>时序异常检测结果图。图像为JPEG格式,使用Base64编码。</td>
+</tr>
+<tr>
 <td><code>csv</code></td>
 <td><code>string</code></td>
 <td>服务器可访问的CSV文件的URL或CSV文件内容的Base64编码结果。CSV文件需要使用UTF-8编码。</td>
@@ -463,7 +468,8 @@ for res in output:
 </table>
 <p><code>result</code>示例如下:</p>
 <pre><code class="language-json">{
-&quot;csv&quot;: &quot;xxxxxx&quot;
+"csv": "xxxxxx",
+"image": "xxxxxx"
 }
 </code></pre></details>
 
@@ -476,42 +482,47 @@ for res in output:
 <pre><code class="language-python">import base64
 import requests
 
-API_URL = &quot;http://localhost:8080/time-series-anomaly-detection&quot; # 服务URL
-csv_path = &quot;./test.csv&quot;
-output_csv_path = &quot;./out.csv&quot;
+API_URL = "http://localhost:8080/time-series-anomaly-detection" # 服务URL
+csv_path = "./test.csv"
+output_image_path = "./out.jpg"
+output_csv_path = "./out.csv"
 
-# 对本地图像进行Base64编码
-with open(csv_path, &quot;rb&quot;) as file:
+# 对本地CSV文件进行Base64编码
+with open(csv_path, "rb") as file:
     csv_bytes = file.read()
-    csv_data = base64.b64encode(csv_bytes).decode(&quot;ascii&quot;)
+    csv_data = base64.b64encode(csv_bytes).decode("ascii")
 
-payload = {&quot;csv&quot;: csv_data}
+payload = {"csv": csv_data}
 
 # 调用API
 response = requests.post(API_URL, json=payload)
 
 # 处理接口返回数据
 assert response.status_code == 200
-result = response.json()[&quot;result&quot;]
-with open(output_csv_path, &quot;wb&quot;) as f:
-    f.write(base64.b64decode(result[&quot;csv&quot;]))
-print(f&quot;Output time-series data saved at  {output_csv_path}&quot;)
+result = response.json()["result"]
+with open(output_image_path, "wb") as f:
+    f.write(base64.b64decode(result["image"]))
+print(f"Output image saved at  {output_image_path}")
+with open(output_csv_path, "wb") as f:
+    f.write(base64.b64decode(result["csv"]))
+print(f"Output time-series data saved at  {output_csv_path}")
 </code></pre></details>
 
 <details><summary>C++</summary>
 
 <pre><code class="language-cpp">#include &lt;iostream&gt;
-#include &quot;cpp-httplib/httplib.h&quot; // https://github.com/Huiyicc/cpp-httplib
-#include &quot;nlohmann/json.hpp&quot; // https://github.com/nlohmann/json
-#include &quot;base64.hpp&quot; // https://github.com/tobiaslocker/base64
+#include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
+#include "nlohmann/json.hpp" // https://github.com/nlohmann/json
+#include "base64.hpp" // https://github.com/tobiaslocker/base64
 
 int main() {
-    httplib::Client client(&quot;localhost:8080&quot;);
-    const std::string csvPath = &quot;./test.csv&quot;;
-    const std::string outputCsvPath = &quot;./out.csv&quot;;
+    httplib::Client client("localhost:8080");
+    const std::string csvPath = "./test.csv";
+    const std::string outputImagePath = "./out.jpg";
+    const std::string outputCsvPath = "./out.csv";
 
     httplib::Headers headers = {
-        {&quot;Content-Type&quot;, &quot;application/json&quot;}
+        {"Content-Type", "application/json"}
     };
 
     // 进行Base64编码
@@ -521,37 +532,49 @@ int main() {
 
     std::vector&lt;char&gt; buffer(size);
     if (!file.read(buffer.data(), size)) {
-        std::cerr &lt;&lt; &quot;Error reading file.&quot; &lt;&lt; std::endl;
+        std::cerr &lt;&lt; "Error reading file." &lt;&lt; std::endl;
         return 1;
     }
     std::string bufferStr(reinterpret_cast&lt;const char*&gt;(buffer.data()), buffer.size());
     std::string encodedCsv = base64::to_base64(bufferStr);
 
     nlohmann::json jsonObj;
-    jsonObj[&quot;csv&quot;] = encodedCsv;
+    jsonObj["csv"] = encodedCsv;
     std::string body = jsonObj.dump();
 
     // 调用API
-    auto response = client.Post(&quot;/time-series-anomaly-detection&quot;, headers, body, &quot;application/json&quot;);
+    auto response = client.Post("/time-series-anomaly-detection", headers, body, "application/json");
     // 处理接口返回数据
     if (response &amp;&amp; response-&gt;status == 200) {
         nlohmann::json jsonResponse = nlohmann::json::parse(response-&gt;body);
-        auto result = jsonResponse[&quot;result&quot;];
+        auto result = jsonResponse["result"];
 
         // 保存数据
-        encodedCsv = result[&quot;csv&quot;];
+        std::string encodedImage = result["image"];
+        std::string decodedString = base64::from_base64(encodedImage);
+        std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
+        std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
+        if (outputImage.is_open()) {
+            outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
+            outputImage.close();
+            std::cout << "Output image data saved at " << outputImagePath << std::endl;
+        } else {
+            std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
+        }
+
+        encodedCsv = result["csv"];
         decodedString = base64::from_base64(encodedCsv);
         std::vector&lt;unsigned char&gt; decodedCsv(decodedString.begin(), decodedString.end());
         std::ofstream outputCsv(outputCsvPath, std::ios::binary | std::ios::out);
         if (outputCsv.is_open()) {
             outputCsv.write(reinterpret_cast&lt;char*&gt;(decodedCsv.data()), decodedCsv.size());
             outputCsv.close();
-            std::cout &lt;&lt; &quot;Output time-series data saved at &quot; &lt;&lt; outputCsvPath &lt;&lt; std::endl;
+            std::cout &lt;&lt; "Output time-series data saved at " &lt;&lt; outputCsvPath &lt;&lt; std::endl;
         } else {
-            std::cerr &lt;&lt; &quot;Unable to open file for writing: &quot; &lt;&lt; outputCsvPath &lt;&lt; std::endl;
+            std::cerr &lt;&lt; "Unable to open file for writing: " &lt;&lt; outputCsvPath &lt;&lt; std::endl;
         }
     } else {
-        std::cout &lt;&lt; &quot;Failed to send HTTP request.&quot; &lt;&lt; std::endl;
+        std::cout &lt;&lt; "Failed to send HTTP request." &lt;&lt; std::endl;
         std::cout &lt;&lt; response-&gt;body &lt;&lt; std::endl;
         return 1;
     }
@@ -574,9 +597,10 @@ import java.util.Base64;
 
 public class Main {
     public static void main(String[] args) throws IOException {
-        String API_URL = &quot;http://localhost:8080/time-series-anomaly-detection&quot;;
-        String csvPath = &quot;./test.csv&quot;;
-        String outputCsvPath = &quot;./out.csv&quot;;
+        String API_URL = "http://localhost:8080/time-series-anomaly-detection";
+        String csvPath = "./test.csv";
+        String outputImagePath = "./out.jpg";
+        String outputCsvPath = "./out.csv";
 
         // 对本地csv进行Base64编码
         File file = new File(csvPath);
@@ -585,11 +609,11 @@ public class Main {
 
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectNode params = objectMapper.createObjectNode();
-        params.put(&quot;csv&quot;, csvData);
+        params.put("csv", csvData);
 
         // 创建 OkHttpClient 实例
         OkHttpClient client = new OkHttpClient();
-        MediaType JSON = MediaType.Companion.get(&quot;application/json; charset=utf-8&quot;);
+        MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");
         RequestBody body = RequestBody.Companion.create(params.toString(), JSON);
         Request request = new Request.Builder()
                 .url(API_URL)
@@ -601,17 +625,24 @@ public class Main {
             if (response.isSuccessful()) {
                 String responseBody = response.body().string();
                 JsonNode resultNode = objectMapper.readTree(responseBody);
-                JsonNode result = resultNode.get(&quot;result&quot;);
+                JsonNode result = resultNode.get("result");
 
                 // 保存返回的数据
-                String base64Csv = result.get(&quot;csv&quot;).asText();
+                String base64Image = result.get("image").asText();
+                byte[] imageBytes = Base64.getDecoder().decode(base64Image);
+                try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
+                    fos.write(imageBytes);
+                }
+                System.out.println("Output image data saved at " + outputImagePath);
+
+                String base64Csv = result.get("csv").asText();
                 byte[] csvBytes = Base64.getDecoder().decode(base64Csv);
                 try (FileOutputStream fos = new FileOutputStream(outputCsvPath)) {
                     fos.write(csvBytes);
                 }
-                System.out.println(&quot;Output time-series data saved at &quot; + outputCsvPath);
+                System.out.println("Output time-series data saved at " + outputCsvPath);
             } else {
-                System.err.println(&quot;Request failed with code: &quot; + response.code());
+                System.err.println("Request failed with code: " + response.code());
             }
         }
     }
@@ -623,45 +654,46 @@ public class Main {
 <pre><code class="language-go">package main
 
 import (
-    &quot;bytes&quot;
-    &quot;encoding/base64&quot;
-    &quot;encoding/json&quot;
-    &quot;fmt&quot;
-    &quot;io/ioutil&quot;
-    &quot;net/http&quot;
+    "bytes"
+    "encoding/base64"
+    "encoding/json"
+    "fmt"
+    "io/ioutil"
+    "net/http"
 )
 
 func main() {
-    API_URL := &quot;http://localhost:8080/time-series-anomaly-detection&quot;
-    csvPath := &quot;./test.csv&quot;;
-    outputCsvPath := &quot;./out.csv&quot;;
+    API_URL := "http://localhost:8080/time-series-anomaly-detection"
+    csvPath := "./test.csv";
+    outputImagePath := "./out.jpg";
+    outputCsvPath := "./out.csv";
 
     // 读取csv文件并进行Base64编码
     csvBytes, err := ioutil.ReadFile(csvPath)
     if err != nil {
-        fmt.Println(&quot;Error reading csv file:&quot;, err)
+        fmt.Println("Error reading csv file:", err)
         return
     }
     csvData := base64.StdEncoding.EncodeToString(csvBytes)
 
-    payload := map[string]string{&quot;csv&quot;: csvData} // Base64编码的文件内容
+    payload := map[string]string{"csv": csvData} // Base64编码的文件内容
     payloadBytes, err := json.Marshal(payload)
     if err != nil {
-        fmt.Println(&quot;Error marshaling payload:&quot;, err)
+        fmt.Println("Error marshaling payload:", err)
         return
     }
 
     // 调用API
     client := &amp;http.Client{}
-    req, err := http.NewRequest(&quot;POST&quot;, API_URL, bytes.NewBuffer(payloadBytes))
+    req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
     if err != nil {
-        fmt.Println(&quot;Error creating request:&quot;, err)
+        fmt.Println("Error creating request:", err)
         return
     }
 
     res, err := client.Do(req)
     if err != nil {
-        fmt.Println(&quot;Error sending request:&quot;, err)
+        fmt.Println("Error sending request:", err)
         return
     }
     defer res.Body.Close()
@@ -669,33 +701,47 @@ func main() {
     // 处理返回数据
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
-        fmt.Println(&quot;Error reading response body:&quot;, err)
+        fmt.Println("Error reading response body:", err)
         return
     }
     type Response struct {
         Result struct {
-            Csv string `json:&quot;csv&quot;`
-        } `json:&quot;result&quot;`
+            Csv string `json:"csv"`
+            Image string `json:"image"`
+        } `json:"result"`
     }
     var respData Response
     err = json.Unmarshal([]byte(string(body)), &amp;respData)
     if err != nil {
-        fmt.Println(&quot;Error unmarshaling response body:&quot;, err)
+        fmt.Println("Error unmarshaling response body:", err)
         return
     }
 
+    // 将Base64编码的图片数据解码并保存为文件
+    outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
+    if err != nil {
+        fmt.Println("Error decoding Base64 image data:", err)
+        return
+    }
+    err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
+    if err != nil {
+        fmt.Println("Error writing image to file:", err)
+        return
+    }
+    fmt.Printf("Output image data saved at %s.jpg", outputImagePath)
+
     // 将Base64编码的csv数据解码并保存为文件
     outputCsvData, err := base64.StdEncoding.DecodeString(respData.Result.Csv)
     if err != nil {
-        fmt.Println(&quot;Error decoding base64 csv data:&quot;, err)
+        fmt.Println("Error decoding base64 csv data:", err)
         return
     }
     err = ioutil.WriteFile(outputCsvPath, outputCsvData, 0644)
     if err != nil {
-        fmt.Println(&quot;Error writing csv to file:&quot;, err)
+        fmt.Println("Error writing csv to file:", err)
         return
     }
-    fmt.Printf(&quot;Output time-series data saved at %s.csv&quot;, outputCsvPath)
+    fmt.Printf("Output time-series data saved at %s.csv", outputCsvPath)
 }
 </code></pre></details>
 
@@ -711,9 +757,10 @@ using Newtonsoft.Json.Linq;
 
 class Program
 {
-    static readonly string API_URL = &quot;http://localhost:8080/time-series-anomaly-detection&quot;;
-    static readonly string csvPath = &quot;./test.csv&quot;;
-    static readonly string outputCsvPath = &quot;./out.csv&quot;;
+    static readonly string API_URL = "http://localhost:8080/time-series-anomaly-detection";
+    static readonly string csvPath = "./test.csv";
+    static readonly string outputImagePath = "./out.jpg";
+    static readonly string outputCsvPath = "./out.csv";
 
     static async Task Main(string[] args)
     {
@@ -723,8 +770,8 @@ class Program
         byte[] csvBytes = File.ReadAllBytes(csvPath);
         string csvData = Convert.ToBase64String(csvBytes);
 
-        var payload = new JObject{ { &quot;csv&quot;, csvData } }; // Base64编码的文件内容
-        var content = new StringContent(payload.ToString(), Encoding.UTF8, &quot;application/json&quot;);
+        var payload = new JObject{ { "csv", csvData } }; // Base64编码的文件内容
+        var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
 
         // 调用API
         HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
@@ -734,11 +781,17 @@ class Program
         string responseBody = await response.Content.ReadAsStringAsync();
         JObject jsonResponse = JObject.Parse(responseBody);
 
+        // 保存图片文件
+        string base64Image = jsonResponse["result"]["image"].ToString();
+        byte[] outputImageBytes = Convert.FromBase64String(base64Image);
+        File.WriteAllBytes(outputImagePath, outputImageBytes);
+        Console.WriteLine($"Output image data saved at {outputImagePath}");
+
         // 保存csv文件
-        string base64Csv = jsonResponse[&quot;result&quot;][&quot;csv&quot;].ToString();
+        string base64Csv = jsonResponse["result"]["csv"].ToString();
         byte[] outputCsvBytes = Convert.FromBase64String(base64Csv);
         File.WriteAllBytes(outputCsvPath, outputCsvBytes);
-        Console.WriteLine($&quot;Output time-series data saved at {outputCsvPath}&quot;);
+        Console.WriteLine($"Output time-series data saved at {outputCsvPath}");
     }
 }
 </code></pre></details>
@@ -749,8 +802,9 @@ class Program
 const fs = require('fs');
 
 const API_URL = 'http://localhost:8080/time-series-anomaly-detection'
-const csvPath = &quot;./test.csv&quot;;
-const outputCsvPath = &quot;./out.csv&quot;;
+const csvPath = "./test.csv";
+const outputImagePath = "./out.jpg";
+const outputCsvPath = "./out.csv";
 
 let config = {
    method: 'POST',
@@ -769,10 +823,17 @@ function encodeFileToBase64(filePath) {
 
 axios.request(config)
 .then((response) =&gt; {
-    const result = response.data[&quot;result&quot;];
+    const result = response.data["result"];
+
+    // 保存图片文件
+    const imageBuffer = Buffer.from(result["image"], 'base64');
+    fs.writeFile(outputImagePath, imageBuffer, (err) =&gt; {
+      if (err) throw err;
+      console.log(`Output image data saved at ${outputImagePath}`);
+    });
 
     // 保存csv文件
-    const csvBuffer = Buffer.from(result[&quot;csv&quot;], 'base64');
+    const csvBuffer = Buffer.from(result["csv"], 'base64');
     fs.writeFile(outputCsvPath, csvBuffer, (err) =&gt; {
       if (err) throw err;
       console.log(`Output time-series data saved at ${outputCsvPath}`);
@@ -787,13 +848,14 @@ axios.request(config)
 
 <pre><code class="language-php">&lt;?php
 
-$API_URL = &quot;http://localhost:8080/time-series-anomaly-detection&quot;; // 服务URL
-$csv_path = &quot;./test.csv&quot;;
-$output_csv_path = &quot;./out.csv&quot;;
+$API_URL = "http://localhost:8080/time-series-anomaly-detection"; // 服务URL
+$csv_path = "./test.csv";
+$output_image_path = "./out.jpg";
+$output_csv_path = "./out.csv";
 
 // 对本地csv文件进行Base64编码
 $csv_data = base64_encode(file_get_contents($csv_path));
-$payload = array(&quot;csv&quot; =&gt; $csv_data); // Base64编码的文件内容
+$payload = array("csv" =&gt; $csv_data); // Base64编码的文件内容
 
 // 调用API
 $ch = curl_init($API_URL);
@@ -805,10 +867,13 @@ $response = curl_exec($ch);
 curl_close($ch);
 
 // 处理接口返回数据
-$result = json_decode($response, true)[&quot;result&quot;];
+$result = json_decode($response, true)["result"];
+
+file_put_contents($output_image_path, base64_decode($result["image"]));
+echo "Output image data saved at " . $output_image_path . "\n";
 
-file_put_contents($output_csv_path, base64_decode($result[&quot;csv&quot;]));
-echo &quot;Output time-series data saved at &quot; . $output_csv_path . &quot;\n&quot;;
+file_put_contents($output_csv_path, base64_decode($result["csv"]));
+echo "Output time-series data saved at " . $output_csv_path . "\n";
 
 ?&gt;
 </code></pre></details>

+ 115 - 53
docs/pipeline_usage/tutorials/time_series_pipelines/time_series_classification.en.md

@@ -420,6 +420,11 @@ Below are the API references for basic serving deployment and multi-language ser
 </thead>
 <tbody>
 <tr>
+<td><code>image</code></td>
+<td><code>string</code> | <code>null</code></td>
+<td>The image of time series classification result. The image is in JPEG format and encoded in Base64.</td>
+</tr>
+<tr>
 <td><code>label</code></td>
 <td><code>string</code></td>
 <td>The class label.</td>
@@ -433,8 +438,9 @@ Below are the API references for basic serving deployment and multi-language ser
 </table>
 <p>An example of <code>result</code> is as follows:</p>
 <pre><code class="language-json">{
-&quot;label&quot;: &quot;running&quot;,
-&quot;score&quot;: 0.97
+"label": "running",
+"score": 0.97,
+"image": "xxxxxx"
 }
 </code></pre></details>
 
@@ -446,38 +452,43 @@ Below are the API references for basic serving deployment and multi-language ser
 <pre><code class="language-python">import base64
 import requests
 
-API_URL = &quot;http://localhost:8080/time-series-classification&quot; # Service URL
-csv_path = &quot;./test.csv&quot;
+API_URL = "http://localhost:8080/time-series-classification" # Service URL
+csv_path = "./test.csv"
+output_image_path = "./out.jpg"
 
 # Encode the local CSV file in Base64
-with open(csv_path, &quot;rb&quot;) as file:
+with open(csv_path, "rb") as file:
     csv_bytes = file.read()
-    csv_data = base64.b64encode(csv_bytes).decode(&quot;ascii&quot;)
+    csv_data = base64.b64encode(csv_bytes).decode("ascii")
 
-payload = {&quot;csv&quot;: csv_data}
+payload = {"csv": csv_data}
 
 # Call the API
 response = requests.post(API_URL, json=payload)
 
 # Process the response data
 assert response.status_code == 200
-result = response.json()[&quot;result&quot;]
-print(f&quot;label: {result['label']}, score: {result['score']}&quot;)
+result = response.json()["result"]
+result = response.json()["result"]
+with open(output_image_path, "wb") as f:
+    f.write(base64.b64decode(result["image"]))
+print(f"label: {result['label']}, score: {result['score']}")
 </code></pre></details>
 
 <details><summary>C++</summary>
 
 <pre><code class="language-cpp">#include &lt;iostream&gt;
-#include &quot;cpp-httplib/httplib.h&quot; // <url id="cu9lu0qn7542c8gg8aog" type="url" status="parsed" title="GitHub - Huiyicc/cpp-httplib: A C++ header-only HTTP/HTTPS server and client library" wc="15064">https://github.com/Huiyicc/cpp-httplib</url>
-#include &quot;nlohmann/json.hpp&quot; // <url id="cu9lu0qn7542c8gg8ap0" type="url" status="parsed" title="" wc="80311">https://github.com/nlohmann/json</url>
-#include &quot;base64.hpp&quot; // <url id="cu9lu0qn7542c8gg8apg" type="url" status="parsed" title="GitHub - tobiaslocker/base64: A modern C++ base64 encoder / decoder" wc="2293">https://github.com/tobiaslocker/base64</url>
+#include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
+#include "nlohmann/json.hpp" // https://github.com/nlohmann/json
+#include "base64.hpp" // https://github.com/tobiaslocker/base64
 
 int main() {
-    httplib::Client client(&quot;localhost:8080&quot;);
-    const std::string csvPath = &quot;./test.csv&quot;;
+    httplib::Client client("localhost:8080");
+    const std::string outputImagePath = "./out.jpg";
+    const std::string csvPath = "./test.csv";
 
     httplib::Headers headers = {
-        {&quot;Content-Type&quot;, &quot;application/json&quot;}
+        {"Content-Type", "application/json"}
     };
 
     // Encode in Base64
@@ -487,25 +498,37 @@ int main() {
 
     std::vector&lt;char&gt; buffer(size);
     if (!file.read(buffer.data(), size)) {
-        std::cerr &lt;&lt; &quot;Error reading file.&quot; &lt;&lt; std::endl;
+        std::cerr &lt;&lt; "Error reading file." &lt;&lt; std::endl;
         return 1;
     }
     std::string bufferStr(reinterpret_cast&lt;const char*&gt;(buffer.data()), buffer.size());
     std::string encodedCsv = base64::to_base64(bufferStr);
 
     nlohmann::json jsonObj;
-    jsonObj[&quot;csv&quot;] = encodedCsv;
+    jsonObj["csv"] = encodedCsv;
     std::string body = jsonObj.dump();
 
     // Call the API
-    auto response = client.Post(&quot;/time-series-classification&quot;, headers, body, &quot;application/json&quot;);
+    auto response = client.Post("/time-series-classification", headers, body, "application/json");
     // Process the response data
     if (response &amp;&amp; response-&gt;status == 200) {
         nlohmann::json jsonResponse = nlohmann::json::parse(response-&gt;body);
-        auto result = jsonResponse[&quot;result&quot;];
-        std::cout &lt;&lt; &quot;label: &quot; &lt;&lt; result[&quot;label&quot;] &lt;&lt; &quot;, score: &quot; &lt;&lt; result[&quot;score&quot;] &lt;&lt; std::endl;
+        auto result = jsonResponse["result"];
+        std::cout &lt;&lt; "label: " &lt;&lt; result["label"] &lt;&lt; ", score: " &lt;&lt; result["score"] &lt;&lt; std::endl;
+
+        std::string encodedImage = result["image"];
+        std::string decodedString = base64::from_base64(encodedImage);
+        std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
+        std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
+        if (outputImage.is_open()) {
+            outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
+            outputImage.close();
+            std::cout << "Output image data saved at " << outputImagePath << std::endl;
+        } else {
+            std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
+        }
     } else {
-        std::cout &lt;&lt; &quot;Failed to send HTTP request.&quot; &lt;&lt; std::endl;
+        std::cout &lt;&lt; "Failed to send HTTP request." &lt;&lt; std::endl;
         std::cout &lt;&lt; response-&gt;body &lt;&lt; std::endl;
         return 1;
     }
@@ -529,6 +552,7 @@ import java.util.Base64;
 public class Main {
     public static void main(String[] args) throws IOException {
         String API_URL = "http://localhost:8080/time-series-classification";
+        String outputImagePath = "./out.jpg";
         String csvPath = "./test.csv";
 
         // Encode the local CSV file using Base64
@@ -556,6 +580,13 @@ public class Main {
                 JsonNode resultNode = objectMapper.readTree(responseBody);
                 JsonNode result = resultNode.get("result");
                 System.out.println("label: " + result.get("label").asText() + ", score: " + result.get("score").asText());
+
+                String base64Image = result.get("image").asText();
+                byte[] imageBytes = Base64.getDecoder().decode(base64Image);
+                try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
+                    fos.write(imageBytes);
+                }
+                System.out.println("Output image data saved at " + outputImagePath);
             } else {
                 System.err.println("Request failed with code: " + response.code());
             }
@@ -569,44 +600,45 @@ public class Main {
 <pre><code class="language-go">package main
 
 import (
-    &quot;bytes&quot;
-    &quot;encoding/base64&quot;
-    &quot;encoding/json&quot;
-    &quot;fmt&quot;
-    &quot;io/ioutil&quot;
-    &quot;net/http&quot;
+    "bytes"
+    "encoding/base64"
+    "encoding/json"
+    "fmt"
+    "io/ioutil"
+    "net/http"
 )
 
 func main() {
-    API_URL := &quot;http://localhost:8080/time-series-classification&quot;
-    csvPath := &quot;./test.csv&quot;;
+    API_URL := "http://localhost:8080/time-series-classification"
+    outputImagePath := "./out.jpg";
+    csvPath := "./test.csv";
 
     // Read the CSV file and encode it with Base64
     csvBytes, err := ioutil.ReadFile(csvPath)
     if err != nil {
-        fmt.Println(&quot;Error reading csv file:&quot;, err)
+        fmt.Println("Error reading csv file:", err)
         return
     }
     csvData := base64.StdEncoding.EncodeToString(csvBytes)
 
-    payload := map[string]string{&quot;csv&quot;: csvData} // Base64-encoded file content
+    payload := map[string]string{"csv": csvData} // Base64-encoded file content
     payloadBytes, err := json.Marshal(payload)
     if err != nil {
-        fmt.Println(&quot;Error marshaling payload:&quot;, err)
+        fmt.Println("Error marshaling payload:", err)
         return
     }
 
     // Call the API
     client := &amp;http.Client{}
-    req, err := http.NewRequest(&quot;POST&quot;, API_URL, bytes.NewBuffer(payloadBytes))
+    req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
     if err != nil {
-        fmt.Println(&quot;Error creating request:&quot;, err)
+        fmt.Println("Error creating request:", err)
         return
     }
 
     res, err := client.Do(req)
     if err != nil {
-        fmt.Println(&quot;Error sending request:&quot;, err)
+        fmt.Println("Error sending request:", err)
         return
     }
     defer res.Body.Close()
@@ -614,23 +646,36 @@ func main() {
     // Process the response data
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
-        fmt.Println(&quot;Error reading response body:&quot;, err)
+        fmt.Println("Error reading response body:", err)
         return
     }
     type Response struct {
         Result struct {
-            Label string `json:&quot;label&quot;`
-            Score string `json:&quot;score&quot;`
-        } `json:&quot;result&quot;`
+            Label string `json:"label"`
+            Score string `json:"score"`
+            Image string `json:"image"`
+        } `json:"result"`
     }
     var respData Response
     err = json.Unmarshal([]byte(string(body)), &amp;respData)
     if err != nil {
-        fmt.Println(&quot;Error unmarshaling response body:&quot;, err)
+        fmt.Println("Error unmarshaling response body:", err)
         return
     }
 
-    fmt.Printf(&quot;label: %s, score: %s\n&quot;, respData.Result.Label, respData.Result.Score)
+    fmt.Printf("label: %s, score: %s\n", respData.Result.Label, respData.Result.Score)
+
+    outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
+    if err != nil {
+        fmt.Println("Error decoding Base64 image data:", err)
+        return
+    }
+    err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
+    if err != nil {
+        fmt.Println("Error writing image to file:", err)
+        return
+    }
+    fmt.Printf("Output image data saved at %s.jpg", outputImagePath)
 }
 </code></pre></details>
 
@@ -646,8 +691,9 @@ using Newtonsoft.Json.Linq;
 
 class Program
 {
-    static readonly string API_URL = &quot;http://localhost:8080/time-series-classification&quot;;
-    static readonly string csvPath = &quot;./test.csv&quot;;
+    static readonly string API_URL = "http://localhost:8080/time-series-classification";
+    static readonly string outputImagePath = "./out.jpg";
+    static readonly string csvPath = "./test.csv";
 
     static async Task Main(string[] args)
     {
@@ -657,8 +703,8 @@ class Program
         byte[] csvBytes = File.ReadAllBytes(csvPath);
         string csvData = Convert.ToBase64String(csvBytes);
 
-        var payload = new JObject{ { &quot;csv&quot;, csvData } }; // Base64-encoded file content
-        var content = new StringContent(payload.ToString(), Encoding.UTF8, &quot;application/json&quot;);
+        var payload = new JObject{ { "csv", csvData } }; // Base64-encoded file content
+        var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
 
         // Call the API
         HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
@@ -668,9 +714,14 @@ class Program
         string responseBody = await response.Content.ReadAsStringAsync();
         JObject jsonResponse = JObject.Parse(responseBody);
 
-        string label = jsonResponse[&quot;result&quot;][&quot;label&quot;].ToString();
-        string score = jsonResponse[&quot;result&quot;][&quot;score&quot;].ToString();
-        Console.WriteLine($&quot;label: {label}, score: {score}&quot;);
+        string label = jsonResponse["result"]["label"].ToString();
+        string score = jsonResponse["result"]["score"].ToString();
+        Console.WriteLine($"label: {label}, score: {score}");
+
+        string base64Image = jsonResponse["result"]["image"].ToString();
+        byte[] outputImageBytes = Convert.FromBase64String(base64Image);
+        File.WriteAllBytes(outputImagePath, outputImageBytes);
+        Console.WriteLine($"Output image data saved at {outputImagePath}");
     }
 }
 </code></pre></details>
@@ -681,6 +732,7 @@ class Program
 const fs = require('fs');
 
 const API_URL = 'http://localhost:8080/time-series-classification';
+const outputImagePath = "./out.jpg";
 const csvPath = './test.csv';
 
 let config = {
@@ -702,6 +754,12 @@ axios.request(config)
 .then((response) => {
     const result = response.data['result'];
     console.log(`label: ${result['label']}, score: ${result['score']}`);
+
+    const imageBuffer = Buffer.from(result["image"], 'base64');
+    fs.writeFile(outputImagePath, imageBuffer, (err) =&gt; {
+      if (err) throw err;
+      console.log(`Output image data saved at ${outputImagePath}`);
+    });
 })
 .catch((error) => {
   console.log(error);
@@ -712,12 +770,13 @@ axios.request(config)
 
 <pre><code class="language-php">&lt;?php
 
-$API_URL = &quot;http://localhost:8080/time-series-classification&quot;; // Service URL
-$csv_path = &quot;./test.csv&quot;;
+$API_URL = "http://localhost:8080/time-series-classification"; // Service URL
+$output_image_path = "./out.jpg";
+$csv_path = "./test.csv";
 
 // Encode the local CSV file using Base64
 $csv_data = base64_encode(file_get_contents($csv_path));
-$payload = array(&quot;csv&quot; =&gt; $csv_data); // Base64-encoded file content
+$payload = array("csv" =&gt; $csv_data); // Base64-encoded file content
 
 // Call the API
 $ch = curl_init($API_URL);
@@ -729,8 +788,11 @@ $response = curl_exec($ch);
 curl_close($ch);
 
 // Process the response data
-$result = json_decode($response, true)[&quot;result&quot;];
-echo &quot;label: &quot; . $result[&quot;label&quot;] . &quot;, score: &quot; . $result[&quot;score&quot;];
+$result = json_decode($response, true)["result"];
+echo "label: " . $result["label"] . ", score: " . $result["score"];
+
+file_put_contents($output_image_path, base64_decode($result["image"]));
+echo "Output image data saved at " . $output_image_path . "\n";
 
 ?&gt;
 </code></pre></details>

+ 126 - 64
docs/pipeline_usage/tutorials/time_series_pipelines/time_series_classification.md

@@ -416,6 +416,11 @@ for res in output:
 </thead>
 <tbody>
 <tr>
+<td><code>image</code></td>
+<td><code>string</code> | <code>null</code></td>
+<td>时序分类结果图。图像为JPEG格式,使用Base64编码。</td>
+</tr>
+<tr>
 <td><code>label</code></td>
 <td><code>string</code></td>
 <td>类别标签。</td>
@@ -429,8 +434,9 @@ for res in output:
 </table>
 <p><code>result</code>示例如下:</p>
 <pre><code class="language-json">{
-&quot;label&quot;: &quot;running&quot;,
-&quot;score&quot;: 0.97
+"label": "running",
+"score": 0.97,
+"image": "xxxxxx"
 }
 </code></pre></details>
 
@@ -443,38 +449,43 @@ for res in output:
 <pre><code class="language-python">import base64
 import requests
 
-API_URL = &quot;http://localhost:8080/time-series-classification&quot; # 服务URL
-csv_path = &quot;./test.csv&quot;
+API_URL = "http://localhost:8080/time-series-classification" # 服务URL
+csv_path = "./test.csv"
+output_image_path = "./out.jpg"
 
-# 对本地图像进行Base64编码
-with open(csv_path, &quot;rb&quot;) as file:
+# 对本地CSV文件进行Base64编码
+with open(csv_path, "rb") as file:
     csv_bytes = file.read()
-    csv_data = base64.b64encode(csv_bytes).decode(&quot;ascii&quot;)
+    csv_data = base64.b64encode(csv_bytes).decode("ascii")
 
-payload = {&quot;csv&quot;: csv_data}
+payload = {"csv": csv_data}
 
 # 调用API
 response = requests.post(API_URL, json=payload)
 
 # 处理接口返回数据
 assert response.status_code == 200
-result = response.json()[&quot;result&quot;]
-print(f&quot;label: {result['label']}, score: {result['score']}&quot;)
+result = response.json()["result"]
+with open(output_image_path, "wb") as f:
+    f.write(base64.b64decode(result["image"]))
+print(f"Output image saved at  {output_image_path}")
+print(f"label: {result['label']}, score: {result['score']}")
 </code></pre></details>
 
 <details><summary>C++</summary>
 
 <pre><code class="language-cpp">#include &lt;iostream&gt;
-#include &quot;cpp-httplib/httplib.h&quot; // https://github.com/Huiyicc/cpp-httplib
-#include &quot;nlohmann/json.hpp&quot; // https://github.com/nlohmann/json
-#include &quot;base64.hpp&quot; // https://github.com/tobiaslocker/base64
+#include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
+#include "nlohmann/json.hpp" // https://github.com/nlohmann/json
+#include "base64.hpp" // https://github.com/tobiaslocker/base64
 
 int main() {
-    httplib::Client client(&quot;localhost:8080&quot;);
-    const std::string csvPath = &quot;./test.csv&quot;;
+    httplib::Client client("localhost:8080");
+    const std::string outputImagePath = "./out.jpg";
+    const std::string csvPath = "./test.csv";
 
     httplib::Headers headers = {
-        {&quot;Content-Type&quot;, &quot;application/json&quot;}
+        {"Content-Type", "application/json"}
     };
 
     // 进行Base64编码
@@ -484,25 +495,37 @@ int main() {
 
     std::vector&lt;char&gt; buffer(size);
     if (!file.read(buffer.data(), size)) {
-        std::cerr &lt;&lt; &quot;Error reading file.&quot; &lt;&lt; std::endl;
+        std::cerr &lt;&lt; "Error reading file." &lt;&lt; std::endl;
         return 1;
     }
     std::string bufferStr(reinterpret_cast&lt;const char*&gt;(buffer.data()), buffer.size());
     std::string encodedCsv = base64::to_base64(bufferStr);
 
     nlohmann::json jsonObj;
-    jsonObj[&quot;csv&quot;] = encodedCsv;
+    jsonObj["csv"] = encodedCsv;
     std::string body = jsonObj.dump();
 
     // 调用API
-    auto response = client.Post(&quot;/time-series-classification&quot;, headers, body, &quot;application/json&quot;);
+    auto response = client.Post("/time-series-classification", headers, body, "application/json");
     // 处理接口返回数据
     if (response &amp;&amp; response-&gt;status == 200) {
         nlohmann::json jsonResponse = nlohmann::json::parse(response-&gt;body);
-        auto result = jsonResponse[&quot;result&quot;];
-        std::cout &lt;&lt; &quot;label: &quot; &lt;&lt; result[&quot;label&quot;] &lt;&lt; &quot;, score: &quot; &lt;&lt; result[&quot;score&quot;] &lt;&lt; std::endl;
+        auto result = jsonResponse["result"];
+        std::cout &lt;&lt; "label: " &lt;&lt; result["label"] &lt;&lt; ", score: " &lt;&lt; result["score"] &lt;&lt; std::endl;
+
+        std::string encodedImage = result["image"];
+        std::string decodedString = base64::from_base64(encodedImage);
+        std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
+        std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
+        if (outputImage.is_open()) {
+            outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
+            outputImage.close();
+            std::cout << "Output image data saved at " << outputImagePath << std::endl;
+        } else {
+            std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
+        }
     } else {
-        std::cout &lt;&lt; &quot;Failed to send HTTP request.&quot; &lt;&lt; std::endl;
+        std::cout &lt;&lt; "Failed to send HTTP request." &lt;&lt; std::endl;
         std::cout &lt;&lt; response-&gt;body &lt;&lt; std::endl;
         return 1;
     }
@@ -525,8 +548,9 @@ import java.util.Base64;
 
 public class Main {
     public static void main(String[] args) throws IOException {
-        String API_URL = &quot;http://localhost:8080/time-series-classification&quot;;
-        String csvPath = &quot;./test.csv&quot;;
+        String API_URL = "http://localhost:8080/time-series-classification";
+        String outputImagePath = "./out.jpg";
+        String csvPath = "./test.csv";
 
         // 对本地csv进行Base64编码
         File file = new File(csvPath);
@@ -535,11 +559,11 @@ public class Main {
 
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectNode params = objectMapper.createObjectNode();
-        params.put(&quot;csv&quot;, csvData);
+        params.put("csv", csvData);
 
         // 创建 OkHttpClient 实例
         OkHttpClient client = new OkHttpClient();
-        MediaType JSON = MediaType.Companion.get(&quot;application/json; charset=utf-8&quot;);
+        MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");
         RequestBody body = RequestBody.Companion.create(params.toString(), JSON);
         Request request = new Request.Builder()
                 .url(API_URL)
@@ -551,10 +575,17 @@ public class Main {
             if (response.isSuccessful()) {
                 String responseBody = response.body().string();
                 JsonNode resultNode = objectMapper.readTree(responseBody);
-                JsonNode result = resultNode.get(&quot;result&quot;);
-                System.out.println(&quot;label: &quot; + result.get(&quot;label&quot;).asText() + &quot;, score: &quot; + result.get(&quot;score&quot;).asText());
+                JsonNode result = resultNode.get("result");
+                System.out.println("label: " + result.get("label").asText() + ", score: " + result.get("score").asText());
+
+                String base64Image = result.get("image").asText();
+                byte[] imageBytes = Base64.getDecoder().decode(base64Image);
+                try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
+                    fos.write(imageBytes);
+                }
+                System.out.println("Output image data saved at " + outputImagePath);
             } else {
-                System.err.println(&quot;Request failed with code: &quot; + response.code());
+                System.err.println("Request failed with code: " + response.code());
             }
         }
     }
@@ -566,44 +597,45 @@ public class Main {
 <pre><code class="language-go">package main
 
 import (
-    &quot;bytes&quot;
-    &quot;encoding/base64&quot;
-    &quot;encoding/json&quot;
-    &quot;fmt&quot;
-    &quot;io/ioutil&quot;
-    &quot;net/http&quot;
+    "bytes"
+    "encoding/base64"
+    "encoding/json"
+    "fmt"
+    "io/ioutil"
+    "net/http"
 )
 
 func main() {
-    API_URL := &quot;http://localhost:8080/time-series-classification&quot;
-    csvPath := &quot;./test.csv&quot;;
+    API_URL := "http://localhost:8080/time-series-classification"
+    outputImagePath := "./out.jpg";
+    csvPath := "./test.csv";
 
     // 读取csv文件并进行Base64编码
     csvBytes, err := ioutil.ReadFile(csvPath)
     if err != nil {
-        fmt.Println(&quot;Error reading csv file:&quot;, err)
+        fmt.Println("Error reading csv file:", err)
         return
     }
     csvData := base64.StdEncoding.EncodeToString(csvBytes)
 
-    payload := map[string]string{&quot;csv&quot;: csvData} // Base64编码的文件内容
+    payload := map[string]string{"csv": csvData} // Base64编码的文件内容
     payloadBytes, err := json.Marshal(payload)
     if err != nil {
-        fmt.Println(&quot;Error marshaling payload:&quot;, err)
+        fmt.Println("Error marshaling payload:", err)
         return
     }
 
     // 调用API
     client := &amp;http.Client{}
-    req, err := http.NewRequest(&quot;POST&quot;, API_URL, bytes.NewBuffer(payloadBytes))
+    req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
     if err != nil {
-        fmt.Println(&quot;Error creating request:&quot;, err)
+        fmt.Println("Error creating request:", err)
         return
     }
 
     res, err := client.Do(req)
     if err != nil {
-        fmt.Println(&quot;Error sending request:&quot;, err)
+        fmt.Println("Error sending request:", err)
         return
     }
     defer res.Body.Close()
@@ -611,23 +643,36 @@ func main() {
     // 处理返回数据
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
-        fmt.Println(&quot;Error reading response body:&quot;, err)
+        fmt.Println("Error reading response body:", err)
         return
     }
     type Response struct {
         Result struct {
-            Label string `json:&quot;label&quot;`
-            Score string `json:&quot;score&quot;`
-        } `json:&quot;result&quot;`
+            Label string `json:"label"`
+            Score string `json:"score"`
+            Image string `json:"image"`
+        } `json:"result"`
     }
     var respData Response
     err = json.Unmarshal([]byte(string(body)), &amp;respData)
     if err != nil {
-        fmt.Println(&quot;Error unmarshaling response body:&quot;, err)
+        fmt.Println("Error unmarshaling response body:", err)
         return
     }
 
-    fmt.Printf(&quot;label: %s, score: %s\n&quot;, respData.Result.Label, respData.Result.Score)
+    fmt.Printf("label: %s, score: %s\n", respData.Result.Label, respData.Result.Score)
+
+    outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
+    if err != nil {
+        fmt.Println("Error decoding Base64 image data:", err)
+        return
+    }
+    err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
+    if err != nil {
+        fmt.Println("Error writing image to file:", err)
+        return
+    }
+    fmt.Printf("Output image data saved at %s.jpg", outputImagePath)
 }
 </code></pre></details>
 
@@ -643,8 +688,9 @@ using Newtonsoft.Json.Linq;
 
 class Program
 {
-    static readonly string API_URL = &quot;http://localhost:8080/time-series-classification&quot;;
-    static readonly string csvPath = &quot;./test.csv&quot;;
+    static readonly string API_URL = "http://localhost:8080/time-series-classification";
+    static readonly string outputImagePath = "./out.jpg";
+    static readonly string csvPath = "./test.csv";
 
     static async Task Main(string[] args)
     {
@@ -654,8 +700,8 @@ class Program
         byte[] csveBytes = File.ReadAllBytes(csvPath);
         string csvData = Convert.ToBase64String(csveBytes);
 
-        var payload = new JObject{ { &quot;csv&quot;, csvData } }; // Base64编码的文件内容
-        var content = new StringContent(payload.ToString(), Encoding.UTF8, &quot;application/json&quot;);
+        var payload = new JObject{ { "csv", csvData } }; // Base64编码的文件内容
+        var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
 
         // 调用API
         HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
@@ -665,9 +711,14 @@ class Program
         string responseBody = await response.Content.ReadAsStringAsync();
         JObject jsonResponse = JObject.Parse(responseBody);
 
-        string label = jsonResponse[&quot;result&quot;][&quot;label&quot;].ToString();
-        string score = jsonResponse[&quot;result&quot;][&quot;score&quot;].ToString();
-        Console.WriteLine($&quot;label: {label}, score: {score}&quot;);
+        string label = jsonResponse["result"]["label"].ToString();
+        string score = jsonResponse["result"]["score"].ToString();
+        Console.WriteLine($"label: {label}, score: {score}");
+
+        string base64Image = jsonResponse["result"]["image"].ToString();
+        byte[] outputImageBytes = Convert.FromBase64String(base64Image);
+        File.WriteAllBytes(outputImagePath, outputImageBytes);
+        Console.WriteLine($"Output image data saved at {outputImagePath}");
     }
 }
 </code></pre></details>
@@ -678,7 +729,8 @@ class Program
 const fs = require('fs');
 
 const API_URL = 'http://localhost:8080/time-series-classification'
-const csvPath = &quot;./test.csv&quot;;
+const outputImagePath = "./out.jpg";
+const csvPath = "./test.csv";
 
 let config = {
    method: 'POST',
@@ -697,8 +749,14 @@ function encodeFileToBase64(filePath) {
 
 axios.request(config)
 .then((response) =&gt; {
-    const result = response.data[&quot;result&quot;];
-    console.log(`label: ${result[&quot;label&quot;]}, score: ${result[&quot;score&quot;]}`);
+    const result = response.data["result"];
+    console.log(`label: ${result["label"]}, score: ${result["score"]}`);
+
+    const imageBuffer = Buffer.from(result["image"], 'base64');
+    fs.writeFile(outputImagePath, imageBuffer, (err) =&gt; {
+      if (err) throw err;
+      console.log(`Output image data saved at ${outputImagePath}`);
+    });
 })
 .catch((error) =&gt; {
   console.log(error);
@@ -709,12 +767,13 @@ axios.request(config)
 
 <pre><code class="language-php">&lt;?php
 
-$API_URL = &quot;http://localhost:8080/time-series-classification&quot;; // 服务URL
-$csv_path = &quot;./test.csv&quot;;
+$API_URL = "http://localhost:8080/time-series-classification"; // 服务URL
+$output_image_path = "./out.jpg";
+$csv_path = "./test.csv";
 
 // 对本地csv文件进行Base64编码
 $csv_data = base64_encode(file_get_contents($csv_path));
-$payload = array(&quot;csv&quot; =&gt; $csv_data); // Base64编码的文件内容
+$payload = array("csv" =&gt; $csv_data); // Base64编码的文件内容
 
 // 调用API
 $ch = curl_init($API_URL);
@@ -726,8 +785,11 @@ $response = curl_exec($ch);
 curl_close($ch);
 
 // 处理接口返回数据
-$result = json_decode($response, true)[&quot;result&quot;];
-echo &quot;label: &quot; . $result[&quot;label&quot;] . &quot;, score: &quot; . $result[&quot;score&quot;];
+$result = json_decode($response, true)["result"];
+echo "label: " . $result["label"] . ", score: " . $result["score"];
+
+file_put_contents($output_image_path, base64_decode($result["image"]));
+echo "Output image data saved at " . $output_image_path . "\n";
 
 ?&gt;
 </code></pre></details>

+ 107 - 43
docs/pipeline_usage/tutorials/time_series_pipelines/time_series_forecasting.en.md

@@ -477,6 +477,11 @@ Below are the API references for basic serving deployment and examples of multi-
 </thead>
 <tbody>
 <tr>
+<td><code>image</code></td>
+<td><code>string</code> | <code>null</code></td>
+<td>The image of time series forecasting result. The image is in JPEG format and encoded in Base64.</td>
+</tr>
+<tr>
 <td><code>csv</code></td>
 <td><code>string</code></td>
 <td>The time-series forecasting result in CSV format. Encoded in UTF-8+Base64.</td>
@@ -485,7 +490,8 @@ Below are the API references for basic serving deployment and examples of multi-
 </table>
 <p>An example of <code>result</code> is as follows:</p>
 <pre><code class="language-json">{
-&quot;csv&quot;: &quot;xxxxxx&quot;
+"csv": "xxxxxx",
+"image": "xxxxxx"
 }
 </code></pre></details>
 
@@ -499,6 +505,7 @@ import requests
 
 API_URL = "http://localhost:8080/time-series-forecasting"  # Service URL
 csv_path = "./test.csv"
+output_image_path = "./out.jpg"
 output_csv_path = "./out.csv"
 
 # Encode the local CSV file using Base64
@@ -514,6 +521,9 @@ response = requests.post(API_URL, json=payload)
 # Process the returned data
 assert response.status_code == 200
 result = response.json()["result"]
+with open(output_image_path, "wb") as f:
+    f.write(base64.b64decode(result["image"]))
+print(f"Output image saved at  {output_image_path}")
 with open(output_csv_path, "wb") as f:
     f.write(base64.b64decode(result["csv"]))
 print(f"Output time-series data saved at {output_csv_path}")
@@ -529,6 +539,7 @@ print(f"Output time-series data saved at {output_csv_path}")
 int main() {
     httplib::Client client("localhost:8080");
     const std::string csvPath = "./test.csv";
+    const std::string outputImagePath = "./out.jpg";
     const std::string outputCsvPath = "./out.csv";
 
     httplib::Headers headers = {
@@ -560,6 +571,18 @@ int main() {
         auto result = jsonResponse["result"];
 
         // Save the data
+        std::string encodedImage = result["image"];
+        std::string decodedString = base64::from_base64(encodedImage);
+        std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
+        std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
+        if (outputImage.is_open()) {
+            outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
+            outputImage.close();
+            std::cout << "Output image data saved at " << outputImagePath << std::endl;
+        } else {
+            std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
+        }
+
         std::string decodedString;
         encodedCsv = result["csv"];
         decodedString = base64::from_base64(encodedCsv);
@@ -596,9 +619,10 @@ import java.util.Base64;
 
 public class Main {
     public static void main(String[] args) throws IOException {
-        String API_URL = &quot;http://localhost:8080/time-series-forecasting&quot;;
-        String csvPath = &quot;./test.csv&quot;;
-        String outputCsvPath = &quot;./out.csv&quot;;
+        String API_URL = "http://localhost:8080/time-series-forecasting";
+        String csvPath = "./test.csv";
+        String outputImagePath = "./out.jpg";
+        String outputCsvPath = "./out.csv";
 
         // Encode the local CSV file using Base64
         File file = new File(csvPath);
@@ -607,11 +631,11 @@ public class Main {
 
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectNode params = objectMapper.createObjectNode();
-        params.put(&quot;csv&quot;, csvData);
+        params.put("csv", csvData);
 
         // Create an OkHttpClient instance
         OkHttpClient client = new OkHttpClient();
-        MediaType JSON = MediaType.Companion.get(&quot;application/json; charset=utf-8&quot;);
+        MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");
         RequestBody body = RequestBody.Companion.create(params.toString(), JSON);
         Request request = new Request.Builder()
                 .url(API_URL)
@@ -623,17 +647,24 @@ public class Main {
             if (response.isSuccessful()) {
                 String responseBody = response.body().string();
                 JsonNode resultNode = objectMapper.readTree(responseBody);
-                JsonNode result = resultNode.get(&quot;result&quot;);
+                JsonNode result = resultNode.get("result");
 
                 // Save the returned data
-                String base64Csv = result.get(&quot;csv&quot;).asText();
+                String base64Image = result.get("image").asText();
+                byte[] imageBytes = Base64.getDecoder().decode(base64Image);
+                try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
+                    fos.write(imageBytes);
+                }
+                System.out.println("Output image data saved at " + outputImagePath);
+
+                String base64Csv = result.get("csv").asText();
                 byte[] csvBytes = Base64.getDecoder().decode(base64Csv);
                 try (FileOutputStream fos = new FileOutputStream(outputCsvPath)) {
                     fos.write(csvBytes);
                 }
-                System.out.println(&quot;Output time-series data saved at &quot; + outputCsvPath);
+                System.out.println("Output time-series data saved at " + outputCsvPath);
             } else {
-                System.err.println(&quot;Request failed with code: &quot; + response.code());
+                System.err.println("Request failed with code: " + response.code());
             }
         }
     }
@@ -645,45 +676,46 @@ public class Main {
 <pre><code class="language-go">package main
 
 import (
-    &quot;bytes&quot;
-    &quot;encoding/base64&quot;
-    &quot;encoding/json&quot;
-    &quot;fmt&quot;
-    &quot;io/ioutil&quot;
-    &quot;net/http&quot;
+    "bytes"
+    "encoding/base64"
+    "encoding/json"
+    "fmt"
+    "io/ioutil"
+    "net/http"
 )
 
 func main() {
-    API_URL := &quot;http://localhost:8080/time-series-forecasting&quot;
-    csvPath := &quot;./test.csv&quot;;
-    outputCsvPath := &quot;./out.csv&quot;;
+    API_URL := "http://localhost:8080/time-series-forecasting"
+    csvPath := "./test.csv";
+    outputImagePath := "./out.jpg";
+    outputCsvPath := "./out.csv";
 
     // Read the csv file and encode it in Base64
     csvBytes, err := ioutil.ReadFile(csvPath)
     if err != nil {
-        fmt.Println(&quot;Error reading csv file:&quot;, err)
+        fmt.Println("Error reading csv file:", err)
         return
     }
     csvData := base64.StdEncoding.EncodeToString(csvBytes)
 
-    payload := map[string]string{&quot;csv&quot;: csvData} // Base64-encoded file content
+    payload := map[string]string{"csv": csvData} // Base64-encoded file content
     payloadBytes, err := json.Marshal(payload)
     if err != nil {
-        fmt.Println(&quot;Error marshaling payload:&quot;, err)
+        fmt.Println("Error marshaling payload:", err)
         return
     }
 
     // Call the API
     client := &amp;http.Client{}
-    req, err := http.NewRequest(&quot;POST&quot;, API_URL, bytes.NewBuffer(payloadBytes))
+    req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
     if err != nil {
-        fmt.Println(&quot;Error creating request:&quot;, err)
+        fmt.Println("Error creating request:", err)
         return
     }
 
     res, err := client.Do(req)
     if err != nil {
-        fmt.Println(&quot;Error sending request:&quot;, err)
+        fmt.Println("Error sending request:", err)
         return
     }
     defer res.Body.Close()
@@ -691,33 +723,46 @@ func main() {
     // Process the response data
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
-        fmt.Println(&quot;Error reading response body:&quot;, err)
+        fmt.Println("Error reading response body:", err)
         return
     }
     type Response struct {
         Result struct {
-            Csv string `json:&quot;csv&quot;`
-        } `json:&quot;result&quot;`
+            Csv string `json:"csv"`
+            Image string `json:"image"`
+        } `json:"result"`
     }
     var respData Response
     err = json.Unmarshal([]byte(string(body)), &amp;respData)
     if err != nil {
-        fmt.Println(&quot;Error unmarshaling response body:&quot;, err)
+        fmt.Println("Error unmarshaling response body:", err)
         return
     }
 
     // Decode the Base64-encoded csv data and save it as a file
+    outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
+    if err != nil {
+        fmt.Println("Error decoding Base64 image data:", err)
+        return
+    }
+    err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
+    if err != nil {
+        fmt.Println("Error writing image to file:", err)
+        return
+    }
+    fmt.Printf("Output image data saved at %s.jpg", outputImagePath)
+
     outputCsvData, err := base64.StdEncoding.DecodeString(respData.Result.Csv)
     if err != nil {
-        fmt.Println(&quot;Error decoding base64 csv data:&quot;, err)
+        fmt.Println("Error decoding base64 csv data:", err)
         return
     }
     err = ioutil.WriteFile(outputCsvPath, outputCsvData, 0644)
     if err != nil {
-        fmt.Println(&quot;Error writing csv to file:&quot;, err)
+        fmt.Println("Error writing csv to file:", err)
         return
     }
-    fmt.Printf(&quot;Output time-series data saved at %s.csv&quot;, outputCsvPath)
+    fmt.Printf("Output time-series data saved at %s.csv", outputCsvPath)
 }
 </code></pre></details>
 
@@ -735,6 +780,7 @@ class Program
 {
     static readonly string API_URL = "http://localhost:8080/time-series-forecasting";
     static readonly string csvPath = "./test.csv";
+    static readonly string outputImagePath = "./out.jpg";
     static readonly string outputCsvPath = "./out.csv";
 
     static async Task Main(string[] args)
@@ -756,6 +802,12 @@ class Program
         string responseBody = await response.Content.ReadAsStringAsync();
         JObject jsonResponse = JObject.Parse(responseBody);
 
+        // Save the image file
+        string base64Image = jsonResponse["result"]["image"].ToString();
+        byte[] outputImageBytes = Convert.FromBase64String(base64Image);
+        File.WriteAllBytes(outputImagePath, outputImageBytes);
+        Console.WriteLine($"Output image data saved at {outputImagePath}");
+
         // Save the CSV file
         string base64Csv = jsonResponse["result"]["csv"].ToString();
         byte[] outputCsvBytes = Convert.FromBase64String(base64Csv);
@@ -771,8 +823,9 @@ class Program
 const fs = require('fs');
 
 const API_URL = 'http://localhost:8080/time-series-forecasting';
-const csvPath = &quot;./test.csv&quot;;
-const outputCsvPath = &quot;./out.csv&quot;;
+const csvPath = "./test.csv";
+const outputImagePath = "./out.jpg";
+const outputCsvPath = "./out.csv";
 
 let config = {
    method: 'POST',
@@ -791,10 +844,17 @@ function encodeFileToBase64(filePath) {
 
 axios.request(config)
 .then((response) =&gt; {
-    const result = response.data[&quot;result&quot;];
+    const result = response.data["result"];
+
+    // Save the image file
+    const imageBuffer = Buffer.from(result["image"], 'base64');
+    fs.writeFile(outputImagePath, imageBuffer, (err) =&gt; {
+      if (err) throw err;
+      console.log(`Output image data saved at ${outputImagePath}`);
+    });
 
     // Save the CSV file
-    const csvBuffer = Buffer.from(result[&quot;csv&quot;], 'base64');
+    const csvBuffer = Buffer.from(result["csv"], 'base64');
     fs.writeFile(outputCsvPath, csvBuffer, (err) =&gt; {
       if (err) throw err;
       console.log(`Output time-series data saved at ${outputCsvPath}`);
@@ -809,13 +869,14 @@ axios.request(config)
 
 <pre><code class="language-php">&lt;?php
 
-$API_URL = &quot;http://localhost:8080/time-series-forecasting&quot;; // Service URL
-$csv_path = &quot;./test.csv&quot;;
-$output_csv_path = &quot;./out.csv&quot;;
+$API_URL = "http://localhost:8080/time-series-forecasting"; // Service URL
+$csv_path = "./test.csv";
+$output_image_path = "./out.jpg";
+$output_csv_path = "./out.csv";
 
 // Encode the local CSV file in Base64
 $csv_data = base64_encode(file_get_contents($csv_path));
-$payload = array(&quot;csv&quot; =&gt; $csv_data); // Base64-encoded file content
+$payload = array("csv" =&gt; $csv_data); // Base64-encoded file content
 
 // Call the API
 $ch = curl_init($API_URL);
@@ -827,10 +888,13 @@ $response = curl_exec($ch);
 curl_close($ch);
 
 // Process the response data
-$result = json_decode($response, true)[&quot;result&quot;];
+$result = json_decode($response, true)["result"];
+
+file_put_contents($output_image_path, base64_decode($result["image"]));
+echo "Output image data saved at " . $output_image_path . "\n";
 
-file_put_contents($output_csv_path, base64_decode($result[&quot;csv&quot;]));
-echo &quot;Output time-series data saved at &quot; . $output_csv_path . &quot;\n&quot;;
+file_put_contents($output_csv_path, base64_decode($result["csv"]));
+echo "Output time-series data saved at " . $output_csv_path . "\n";
 
 ?&gt;
 </code></pre></details>

+ 141 - 76
docs/pipeline_usage/tutorials/time_series_pipelines/time_series_forecasting.md

@@ -487,6 +487,11 @@ for res in output:
 </thead>
 <tbody>
 <tr>
+<td><code>image</code></td>
+<td><code>string</code> | <code>null</code></td>
+<td>时序预测结果图。图像为JPEG格式,使用Base64编码。</td>
+</tr>
+<tr>
 <td><code>csv</code></td>
 <td><code>string</code></td>
 <td>CSV格式的时序预测结果。使用UTF-8+Base64编码。</td>
@@ -495,7 +500,8 @@ for res in output:
 </table>
 <p><code>result</code>示例如下:</p>
 <pre><code class="language-json">{
-&quot;csv&quot;: &quot;xxxxxx&quot;
+"csv": "xxxxxx",
+"image": "xxxxxx"
 }
 </code></pre></details>
 
@@ -508,42 +514,47 @@ for res in output:
 <pre><code class="language-python">import base64
 import requests
 
-API_URL = &quot;http://localhost:8080/time-series-forecasting&quot; # 服务URL
-csv_path = &quot;./test.csv&quot;
-output_csv_path = &quot;./out.csv&quot;
+API_URL = "http://localhost:8080/time-series-forecasting" # 服务URL
+csv_path = "./test.csv"
+output_image_path = "./out.jpg"
+output_csv_path = "./out.csv"
 
-# 对本地csv进行Base64编码
-with open(csv_path, &quot;rb&quot;) as file:
+# 对本地CSV文件进行Base64编码
+with open(csv_path, "rb") as file:
     csv_bytes = file.read()
-    csv_data = base64.b64encode(csv_bytes).decode(&quot;ascii&quot;)
+    csv_data = base64.b64encode(csv_bytes).decode("ascii")
 
-payload = {&quot;csv&quot;: csv_data}
+payload = {"csv": csv_data}
 
 # 调用API
 response = requests.post(API_URL, json=payload)
 
 # 处理接口返回数据
 assert response.status_code == 200
-result = response.json()[&quot;result&quot;]
-with open(output_csv_path, &quot;wb&quot;) as f:
-    f.write(base64.b64decode(result[&quot;csv&quot;]))
-print(f&quot;Output time-series data saved at  {output_csv_path}&quot;)
+result = response.json()["result"]
+with open(output_image_path, "wb") as f:
+    f.write(base64.b64decode(result["image"]))
+print(f"Output image saved at  {output_image_path}")
+with open(output_csv_path, "wb") as f:
+    f.write(base64.b64decode(result["csv"]))
+print(f"Output time-series data saved at  {output_csv_path}")
 </code></pre></details>
 
 <details><summary>C++</summary>
 
 <pre><code class="language-cpp">#include &lt;iostream&gt;
-#include &quot;cpp-httplib/httplib.h&quot; // https://github.com/Huiyicc/cpp-httplib
-#include &quot;nlohmann/json.hpp&quot; // https://github.com/nlohmann/json
-#include &quot;base64.hpp&quot; // https://github.com/tobiaslocker/base64
+#include "cpp-httplib/httplib.h" // https://github.com/Huiyicc/cpp-httplib
+#include "nlohmann/json.hpp" // https://github.com/nlohmann/json
+#include "base64.hpp" // https://github.com/tobiaslocker/base64
 
 int main() {
-    httplib::Client client(&quot;localhost:8080&quot;);
-    const std::string csvPath = &quot;./test.csv&quot;;
-    const std::string outputCsvPath = &quot;./out.csv&quot;;
+    httplib::Client client("localhost:8080");
+    const std::string csvPath = "./test.csv";
+    const std::string outputImagePath = "./out.jpg";
+    const std::string outputCsvPath = "./out.csv";
 
     httplib::Headers headers = {
-        {&quot;Content-Type&quot;, &quot;application/json&quot;}
+        {"Content-Type", "application/json"}
     };
 
     // 进行Base64编码
@@ -553,37 +564,49 @@ int main() {
 
     std::vector&lt;char&gt; buffer(size);
     if (!file.read(buffer.data(), size)) {
-        std::cerr &lt;&lt; &quot;Error reading file.&quot; &lt;&lt; std::endl;
+        std::cerr &lt;&lt; "Error reading file." &lt;&lt; std::endl;
         return 1;
     }
     std::string bufferStr(reinterpret_cast&lt;const char*&gt;(buffer.data()), buffer.size());
     std::string encodedCsv = base64::to_base64(bufferStr);
 
     nlohmann::json jsonObj;
-    jsonObj[&quot;csv&quot;] = encodedCsv;
+    jsonObj["csv"] = encodedCsv;
     std::string body = jsonObj.dump();
 
     // 调用API
-    auto response = client.Post(&quot;/time-series-forecasting&quot;, headers, body, &quot;application/json&quot;);
+    auto response = client.Post("/time-series-forecasting", headers, body, "application/json");
     // 处理接口返回数据
     if (response &amp;&amp; response-&gt;status == 200) {
         nlohmann::json jsonResponse = nlohmann::json::parse(response-&gt;body);
-        auto result = jsonResponse[&quot;result&quot;];
+        auto result = jsonResponse["result"];
 
         // 保存数据
-        encodedCsv = result[&quot;csv&quot;];
+        std::string encodedImage = result["image"];
+        std::string decodedString = base64::from_base64(encodedImage);
+        std::vector<unsigned char> decodedImage(decodedString.begin(), decodedString.end());
+        std::ofstream outputImage(outputImagePath, std::ios::binary | std::ios::out);
+        if (outputImage.is_open()) {
+            outputImage.write(reinterpret_cast<char*>(decodedImage.data()), decodedImage.size());
+            outputImage.close();
+            std::cout << "Output image data saved at " << outputImagePath << std::endl;
+        } else {
+            std::cerr << "Unable to open file for writing: " << outputImagePath << std::endl;
+        }
+
+        encodedCsv = result["csv"];
         decodedString = base64::from_base64(encodedCsv);
         std::vector&lt;unsigned char&gt; decodedCsv(decodedString.begin(), decodedString.end());
         std::ofstream outputCsv(outputCsvPath, std::ios::binary | std::ios::out);
         if (outputCsv.is_open()) {
             outputCsv.write(reinterpret_cast&lt;char*&gt;(decodedCsv.data()), decodedCsv.size());
             outputCsv.close();
-            std::cout &lt;&lt; &quot;Output time-series data saved at &quot; &lt;&lt; outputCsvPath &lt;&lt; std::endl;
+            std::cout &lt;&lt; "Output time-series data saved at " &lt;&lt; outputCsvPath &lt;&lt; std::endl;
         } else {
-            std::cerr &lt;&lt; &quot;Unable to open file for writing: &quot; &lt;&lt; outputCsvPath &lt;&lt; std::endl;
+            std::cerr &lt;&lt; "Unable to open file for writing: " &lt;&lt; outputCsvPath &lt;&lt; std::endl;
         }
     } else {
-        std::cout &lt;&lt; &quot;Failed to send HTTP request.&quot; &lt;&lt; std::endl;
+        std::cout &lt;&lt; "Failed to send HTTP request." &lt;&lt; std::endl;
         std::cout &lt;&lt; response-&gt;body &lt;&lt; std::endl;
         return 1;
     }
@@ -606,9 +629,10 @@ import java.util.Base64;
 
 public class Main {
     public static void main(String[] args) throws IOException {
-        String API_URL = &quot;http://localhost:8080/time-series-forecasting&quot;;
-        String csvPath = &quot;./test.csv&quot;;
-        String outputCsvPath = &quot;./out.csv&quot;;
+        String API_URL = "http://localhost:8080/time-series-forecasting";
+        String csvPath = "./test.csv";
+        String outputImagePath = "./out.jpg";
+        String outputCsvPath = "./out.csv";
 
         // 对本地csv进行Base64编码
         File file = new File(csvPath);
@@ -617,11 +641,11 @@ public class Main {
 
         ObjectMapper objectMapper = new ObjectMapper();
         ObjectNode params = objectMapper.createObjectNode();
-        params.put(&quot;csv&quot;, csvData);
+        params.put("csv", csvData);
 
         // 创建 OkHttpClient 实例
         OkHttpClient client = new OkHttpClient();
-        MediaType JSON = MediaType.Companion.get(&quot;application/json; charset=utf-8&quot;);
+        MediaType JSON = MediaType.Companion.get("application/json; charset=utf-8");
         RequestBody body = RequestBody.Companion.create(params.toString(), JSON);
         Request request = new Request.Builder()
                 .url(API_URL)
@@ -633,17 +657,24 @@ public class Main {
             if (response.isSuccessful()) {
                 String responseBody = response.body().string();
                 JsonNode resultNode = objectMapper.readTree(responseBody);
-                JsonNode result = resultNode.get(&quot;result&quot;);
+                JsonNode result = resultNode.get("result");
 
                 // 保存返回的数据
-                String base64Csv = result.get(&quot;csv&quot;).asText();
+                String base64Image = result.get("image").asText();
+                byte[] imageBytes = Base64.getDecoder().decode(base64Image);
+                try (FileOutputStream fos = new FileOutputStream(outputImagePath)) {
+                    fos.write(imageBytes);
+                }
+                System.out.println("Output image data saved at " + outputImagePath);
+
+                String base64Csv = result.get("csv").asText();
                 byte[] csvBytes = Base64.getDecoder().decode(base64Csv);
                 try (FileOutputStream fos = new FileOutputStream(outputCsvPath)) {
                     fos.write(csvBytes);
                 }
-                System.out.println(&quot;Output time-series data saved at &quot; + outputCsvPath);
+                System.out.println("Output time-series data saved at " + outputCsvPath);
             } else {
-                System.err.println(&quot;Request failed with code: &quot; + response.code());
+                System.err.println("Request failed with code: " + response.code());
             }
         }
     }
@@ -655,45 +686,46 @@ public class Main {
 <pre><code class="language-go">package main
 
 import (
-    &quot;bytes&quot;
-    &quot;encoding/base64&quot;
-    &quot;encoding/json&quot;
-    &quot;fmt&quot;
-    &quot;io/ioutil&quot;
-    &quot;net/http&quot;
+    "bytes"
+    "encoding/base64"
+    "encoding/json"
+    "fmt"
+    "io/ioutil"
+    "net/http"
 )
 
 func main() {
-    API_URL := &quot;http://localhost:8080/time-series-forecasting&quot;
-    csvPath := &quot;./test.csv&quot;;
-    outputCsvPath := &quot;./out.csv&quot;;
+    API_URL := "http://localhost:8080/time-series-forecasting"
+    csvPath := "./test.csv";
+    outputImagePath := "./out.jpg";
+    outputCsvPath := "./out.csv";
 
     // 读取csv文件并进行Base64编码
     csvBytes, err := ioutil.ReadFile(csvPath)
     if err != nil {
-        fmt.Println(&quot;Error reading csv file:&quot;, err)
+        fmt.Println("Error reading csv file:", err)
         return
     }
     csvData := base64.StdEncoding.EncodeToString(csvBytes)
 
-    payload := map[string]string{&quot;csv&quot;: csvData} // Base64编码的文件内容
+    payload := map[string]string{"csv": csvData} // Base64编码的文件内容
     payloadBytes, err := json.Marshal(payload)
     if err != nil {
-        fmt.Println(&quot;Error marshaling payload:&quot;, err)
+        fmt.Println("Error marshaling payload:", err)
         return
     }
 
     // 调用API
     client := &amp;http.Client{}
-    req, err := http.NewRequest(&quot;POST&quot;, API_URL, bytes.NewBuffer(payloadBytes))
+    req, err := http.NewRequest("POST", API_URL, bytes.NewBuffer(payloadBytes))
     if err != nil {
-        fmt.Println(&quot;Error creating request:&quot;, err)
+        fmt.Println("Error creating request:", err)
         return
     }
 
     res, err := client.Do(req)
     if err != nil {
-        fmt.Println(&quot;Error sending request:&quot;, err)
+        fmt.Println("Error sending request:", err)
         return
     }
     defer res.Body.Close()
@@ -701,33 +733,47 @@ func main() {
     // 处理返回数据
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
-        fmt.Println(&quot;Error reading response body:&quot;, err)
+        fmt.Println("Error reading response body:", err)
         return
     }
     type Response struct {
         Result struct {
-            Csv string `json:&quot;csv&quot;`
-        } `json:&quot;result&quot;`
+            Csv string `json:"csv"`
+            Image string `json:"image"`
+        } `json:"result"`
     }
     var respData Response
     err = json.Unmarshal([]byte(string(body)), &amp;respData)
     if err != nil {
-        fmt.Println(&quot;Error unmarshaling response body:&quot;, err)
+        fmt.Println("Error unmarshaling response body:", err)
         return
     }
 
+    // 将Base64编码的图片数据解码并保存为文件
+    outputImageData, err := base64.StdEncoding.DecodeString(respData.Result.Image)
+    if err != nil {
+        fmt.Println("Error decoding Base64 image data:", err)
+        return
+    }
+    err = ioutil.WriteFile(outputImagePath, outputImageData, 0644)
+    if err != nil {
+        fmt.Println("Error writing image to file:", err)
+        return
+    }
+    fmt.Printf("Output image data saved at %s.jpg", outputImagePath)
+
     // 将Base64编码的csv数据解码并保存为文件
     outputCsvData, err := base64.StdEncoding.DecodeString(respData.Result.Csv)
     if err != nil {
-        fmt.Println(&quot;Error decoding base64 csv data:&quot;, err)
+        fmt.Println("Error decoding base64 csv data:", err)
         return
     }
     err = ioutil.WriteFile(outputCsvPath, outputCsvData, 0644)
     if err != nil {
-        fmt.Println(&quot;Error writing csv to file:&quot;, err)
+        fmt.Println("Error writing csv to file:", err)
         return
     }
-    fmt.Printf(&quot;Output time-series data saved at %s.csv&quot;, outputCsvPath)
+    fmt.Printf("Output time-series data saved at %s.csv", outputCsvPath)
 }
 </code></pre></details>
 
@@ -743,9 +789,10 @@ using Newtonsoft.Json.Linq;
 
 class Program
 {
-    static readonly string API_URL = &quot;http://localhost:8080/time-series-forecasting&quot;;
-    static readonly string csvPath = &quot;./test.csv&quot;;
-    static readonly string outputCsvPath = &quot;./out.csv&quot;;
+    static readonly string API_URL = "http://localhost:8080/time-series-forecasting";
+    static readonly string csvPath = "./test.csv";
+    static readonly string outputImagePath = "./out.jpg";
+    static readonly string outputCsvPath = "./out.csv";
 
     static async Task Main(string[] args)
     {
@@ -755,8 +802,8 @@ class Program
         byte[] csvBytes = File.ReadAllBytes(csvPath);
         string csvData = Convert.ToBase64String(csvBytes);
 
-        var payload = new JObject{ { &quot;csv&quot;, csvData } }; // Base64编码的文件内容
-        var content = new StringContent(payload.ToString(), Encoding.UTF8, &quot;application/json&quot;);
+        var payload = new JObject{ { "csv", csvData } }; // Base64编码的文件内容
+        var content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
 
         // 调用API
         HttpResponseMessage response = await httpClient.PostAsync(API_URL, content);
@@ -766,11 +813,17 @@ class Program
         string responseBody = await response.Content.ReadAsStringAsync();
         JObject jsonResponse = JObject.Parse(responseBody);
 
+        // 保存图片文件
+        string base64Image = jsonResponse["result"]["image"].ToString();
+        byte[] outputImageBytes = Convert.FromBase64String(base64Image);
+        File.WriteAllBytes(outputImagePath, outputImageBytes);
+        Console.WriteLine($"Output image at {outputImagePath}");outputC
+
         // 保存csv文件
-        string base64Csv = jsonResponse[&quot;result&quot;][&quot;csv&quot;].ToString();
+        string base64Csv = jsonResponse["result"]["csv"].ToString();
         byte[] outputCsvBytes = Convert.FromBase64String(base64Csv);
         File.WriteAllBytes(outputCsvPath, outputCsvBytes);
-        Console.WriteLine($&quot;Output time-series data saved at {outputCsvPath}&quot;);
+        Console.WriteLine($"Output time-series data saved at {outputCsvPath}");
     }
 }
 </code></pre></details>
@@ -781,8 +834,9 @@ class Program
 const fs = require('fs');
 
 const API_URL = 'http://localhost:8080/time-series-forecasting'
-const csvPath = &quot;./test.csv&quot;;
-const outputCsvPath = &quot;./out.csv&quot;;
+const csvPath = "./test.csv";
+const outputImagePath = "./out.jpg";
+const outputCsvPath = "./out.csv";
 
 let config = {
    method: 'POST',
@@ -801,10 +855,17 @@ function encodeFileToBase64(filePath) {
 
 axios.request(config)
 .then((response) =&gt; {
-    const result = response.data[&quot;result&quot;];
+    const result = response.data["result"];
+
+    // 保存图片文件
+    const imageBuffer = Buffer.from(result["image"], 'base64');
+    fs.writeFile(outputImagePath, imageBuffer, (err) =&gt; {
+      if (err) throw err;
+      console.log(`Output image data saved at ${outputImagePath}`);
+    });
 
     // 保存csv文件
-    const csvBuffer = Buffer.from(result[&quot;csv&quot;], 'base64');
+    const csvBuffer = Buffer.from(result["csv"], 'base64');
     fs.writeFile(outputCsvPath, csvBuffer, (err) =&gt; {
       if (err) throw err;
       console.log(`Output time-series data saved at ${outputCsvPath}`);
@@ -819,13 +880,14 @@ axios.request(config)
 
 <pre><code class="language-php">&lt;?php
 
-$API_URL = &quot;http://localhost:8080/time-series-forecasting&quot;; // 服务URL
-$csv_path = &quot;./test.csv&quot;;
-$output_csv_path = &quot;./out.csv&quot;;
+$API_URL = "http://localhost:8080/time-series-forecasting"; // 服务URL
+$csv_path = "./test.csv";
+$output_image_path = "./out.jpg";
+$output_csv_path = "./out.csv";
 
 // 对本地csv文件进行Base64编码
 $csv_data = base64_encode(file_get_contents($csv_path));
-$payload = array(&quot;csv&quot; =&gt; $csv_data); // Base64编码的文件内容
+$payload = array("csv" =&gt; $csv_data); // Base64编码的文件内容
 
 // 调用API
 $ch = curl_init($API_URL);
@@ -837,10 +899,13 @@ $response = curl_exec($ch);
 curl_close($ch);
 
 // 处理接口返回数据
-$result = json_decode($response, true)[&quot;result&quot;];
+$result = json_decode($response, true)["result"];
+
+file_put_contents($output_image_path, base64_decode($result["image"]));
+echo "Output image data saved at " . $output_image_path . "\n";
 
-file_put_contents($output_csv_path, base64_decode($result[&quot;csv&quot;]));
-echo &quot;Output time-series data saved at &quot; . $output_csv_path . &quot;\n&quot;;
+file_put_contents($output_csv_path, base64_decode($result["csv"]));
+echo "Output time-series data saved at " . $output_csv_path . "\n";
 
 ?&gt;
 </code></pre></details>