将代理响应呈现为可视化图表

对话式分析 API 可以根据用户提出的问题生成交互式可视化图表。该 API 会以 Vega-Lite JSON 配置或 SVG 图片(适用于 Looker 数据源,且仅在 v1alphav1beta API 版本中)的形式返回图表。您还可以指示代理根据特定要求生成图表。可视化图表是根据回答用户问题时获得的数据结果创建的。

条形图显示了加利福尼亚州 20-30 岁和 40-50 岁年龄段的裤子总促销价和订单数量。

面积图显示了过去 12 个月的月总销售价格表现,最高为 3,395.12 美元,平均为 2,517.68 美元。

支持的可视化图表

该 API 使用 Vega-Lite 创建可视化图表,并支持所有标准 Vega-Lite 功能。支持以下图表类型:

  • 条形图
  • 地理形状
  • 热图
  • 折线图(时序)
  • 饼图
  • 散点图

图表的生成方式

代理会识别相关的数据结果,并将其传递给子代理。此子代理会执行 Python 代码,以生成图表的 Vega-Lite JSON 配置。该 API 会使用对话上下文来更好地了解用户在生成图表时的意图。借助 Python,该 API 可以创建更复杂的图表。

代理可能会执行一些小的数据转换(例如汇总或应用过滤条件),以使图表更具相关性和可读性。

输出格式

图表以 chart 结果消息的形式返回,并且可以采用以下格式提供:

您可以使用上下文中的 ChartOptions 字段请求图片。当用户请求图片时,该 API 会同时提供图片和 Vega-Lite JSON 输出。

将代理响应呈现为可视化图表

本部分演示了如何使用 Python SDK 从对话式分析 API 响应中提供的图表规范呈现可视化图表。示例代码从回答的 chart 字段中提取图表规范(采用 Vega-Lite 格式),并使用 Altair 库(基于 Vega-Lite 构建)呈现图表、将其保存为图片并显示。

如需详细了解如何使用 Vega-Lite 和 Vega-Lite 生态系统呈现图表,请参阅用于创作 Vega-Lite 可视化图表的工具

示例:根据 Vega-Lite 输出呈现图表

此示例展示了如何根据 Conversational Analytics API 代理回答呈现条形图。示例发送包含以下提示的请求:

"Create a bar graph that shows the top five states by the total number of airports."

示例代码定义了以下辅助函数:

  • render_chart_response:从 chart 消息中提取 Vega-Lite 配置、将其转换为 Altair 库可使用的格式、呈现图表、将其保存到 chart.png,并进行显示。
  • chat:使用 inline_context 变量和当前的 messages 列表向 Conversational Analytics API 发送请求,处理流式回答;如果返回图表,则调用 render_chart_response 以显示该图表。

如需使用以下示例代码,请替换以下内容:

  • sqlgen-testing已启用所需 API 的结算项目的 ID。
  • Create a bar graph that shows the top five states by the total number of airports:您要发送给对话式分析 API 的提示。
from google.cloud import geminidataanalytics
from google.protobuf.json_format import MessageToDict
import altair as alt
import proto

# Helper function for rendering chart response
def render_chart_response(resp):
  def _convert(v):
    if isinstance(v, proto.marshal.collections.maps.MapComposite):
      return {k: _convert(val) for k, val in v.items()}
    elif isinstance(v, proto.marshal.collections.RepeatedComposite):
      return [_convert(el) for el in v]
    elif isinstance(v, (int, float, str, bool, type(None))):
      return v
    else:
      return MessageToDict(v)

  try:
    vega_config = _convert(resp.result.vega_config)
    chart = alt.Chart.from_dict(vega_config)
    chart.save('chart.png')
    chart.display()
    print("Chart rendered and saved as chart.png")
  except Exception as e:
    print(f"Error rendering chart: {e}")

# Helper function for calling the API
def chat(q: str, inline_context, messages):
  billing_project = "sqlgen-testing"

  input_message = geminidataanalytics.Message(
      user_message=geminidataanalytics.UserMessage(text=q)
  )
  messages.append(input_message)

  client = geminidataanalytics.DataChatServiceClient()
  request = geminidataanalytics.ChatRequest(
      inline_context=inline_context,
      parent=f"projects/{billing_project}/locations/global",
      messages=messages,
  )

  # Make the request
  try:
    stream = client.chat(request=request)

    for reply in stream:
      if reply.system_message and hasattr(reply.system_message, 'chart'):
        # ChartMessage includes `query` for generating a chart and `result` with the generated chart.
        if hasattr(reply.system_message.chart, 'result'):
          print("Chart result found in response.")
          render_chart_response(reply.system_message.chart)
        else:
          print("Chart message found, but no result yet.")
      # Append system messages to maintain context for follow-up turns
      if reply.system_message:
          messages.append(geminidataanalytics.Message(system_message=reply.system_message))

  except Exception as e:
    print(f"Error calling API: {e}")

# Example Usage:
# Assuming 'inline_context' and 'messages' are initialized as per "Build a data agent using the Python SDK"
# Example initialization (replace with your actual context and message history):
# inline_context = geminidataanalytics.InlineContext(...)
# messages = []

# Send the prompt to make a bar graph
chat("Create a bar graph that shows the top five states by the total number of airports")