plot-agent 0.1.2__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,99 +7,19 @@ from plotly.subplots import make_subplots
7
7
  from io import StringIO
8
8
  import traceback
9
9
  import sys
10
- import re
11
10
  from typing import Dict, List, Optional, Any
12
11
 
13
12
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
14
13
  from langchain_core.messages import AIMessage, HumanMessage
15
14
  from langchain_core.tools import Tool, StructuredTool
16
- from pydantic import BaseModel, Field
17
15
  from langchain.agents import AgentExecutor, create_openai_tools_agent
18
16
  from langchain_openai import ChatOpenAI
19
-
20
-
21
- DEFAULT_SYSTEM_PROMPT = """
22
- You are an expert data visualization assistant that helps users create Plotly visualizations in Python.
23
- Your job is to generate Python and Plotly code based on the user's request that will create the desired visualization
24
- of their pandas DataFrame (df).
25
-
26
- You have access to a pandas df with the following information:
27
-
28
- df.info():
29
- ```plaintext
30
- {df_info}
31
- ```
32
-
33
- df.head():
34
- ```plaintext
35
- {df_head}
36
- ```
37
-
38
- {sql_context}
39
-
40
- NOTES:
41
- - You must use the execute_plotly_code(generated_code) tool run your code and use the does_fig_exist() tool to check that a fig object is available for display.
42
- - You must paste the full code, not just a reference to the code.
43
- - You must not use fig.show() in your code as it will ultimately be executed elsewhere in a headless environment.
44
- - If you need to do any data cleaning or wrangling, do it in the code before generating the plotly code as preprocessing steps assume the data is in the pandas 'df' object.
45
-
46
- TOOLS:
47
- - execute_plotly_code(generated_code) to execute the generated code.
48
- - does_fig_exist() to check that a fig object is available for display. This tool takes no arguments.
49
- - view_generated_code() to view the generated code if need to fix it. This tool takes no arguments.
50
-
51
- IMPORTANT CODE FORMATTING INSTRUCTIONS:
52
- 1. Include thorough, detailed comments in your code to explain what each section does.
53
- 2. Use descriptive variable names.
54
- 3. DO NOT include fig.show() in your code - the visualization will be rendered externally.
55
- 4. Ensure your code creates a variable named 'fig' that contains the Plotly figure object.
56
-
57
- When a user asks for a visualization:
58
- 1. YOU MUST ALWAYS use the execute_plotly_code(generated_code) tool to test and run your code.
59
- 2. If there are errors, view the generated code using view_generated_code() and fix the code.
60
- 3. Check that a figure object is available using does_fig_exist(). does_fig_exist() takes no arguments.
61
- 4. If the figure object is not available, repeat the process until it is available.
62
-
63
- IMPORTANT: The code you generate MUST be executed using the execute_plotly_code tool or no figure will be created!
64
- YOU MUST CALL execute_plotly_code WITH THE FULL CODE, NOT JUST A REFERENCE TO THE CODE.
65
-
66
- YOUR WORKFLOW MUST BE:
67
- 1. execute_plotly_code(generated_code) to make sure the code is ran and a figure object is created.
68
- 2. check that a figure object is available using does_fig_exist() to make sure the figure object was created.
69
- 3. if there are errors, view the generated code using view_generated_code() to see what went wrong.
70
- 4. fix the code and execute it again with execute_plotly_code(generated_code) to make sure the figure object is created.
71
- 5. repeat until the figure object is available.
72
-
73
- Always return the final working code (with all the comments) to the user along with an explanation of what the visualization shows.
74
- Make sure to follow best practices for data visualization, such as appropriate chart types, labels, and colors.
75
-
76
- Remember that users may want to iterate on their visualizations, so be responsive to requests for changes.
77
- """
78
-
79
-
80
- # Define input schemas for the tools
81
- class PlotDescriptionInput(BaseModel):
82
- plot_description: str = Field(
83
- ..., description="Description of the plot the user wants to create"
84
- )
85
-
86
-
87
- class GeneratedCodeInput(BaseModel):
88
- generated_code: str = Field(
89
- ..., description="Python code that creates a Plotly figure"
90
- )
91
-
92
-
93
- class DoesFigExistInput(BaseModel):
94
- """Model indicating that the does_fig_exist function takes no arguments."""
95
-
96
- pass
97
-
98
-
99
- class ViewGeneratedCodeInput(BaseModel):
100
- """Model indicating that the view_generated_code function takes no arguments."""
101
-
102
- pass
17
+ from plot_agent.prompt import DEFAULT_SYSTEM_PROMPT
18
+ from plot_agent.models import (
19
+ GeneratedCodeInput,
20
+ DoesFigExistInput,
21
+ ViewGeneratedCodeInput,
22
+ )
103
23
 
104
24
 
105
25
  class PlotlyAgentExecutionEnvironment:
@@ -176,13 +96,25 @@ class PlotlyAgent:
176
96
  A class that uses an LLM to generate Plotly code based on a user's plot description.
177
97
  """
178
98
 
179
- def __init__(self, model="gpt-4o-mini", system_prompt: Optional[str] = None):
99
+ def __init__(
100
+ self,
101
+ model="gpt-4o-mini",
102
+ system_prompt: Optional[str] = None,
103
+ verbose: bool = True,
104
+ max_iterations: int = 10,
105
+ early_stopping_method: str = "force",
106
+ handle_parsing_errors: bool = True,
107
+ ):
180
108
  """
181
109
  Initialize the PlotlyAgent.
182
110
 
183
111
  Args:
184
112
  model (str): The model to use for the LLM.
185
113
  system_prompt (Optional[str]): The system prompt to use for the LLM.
114
+ verbose (bool): Whether to print verbose output from the agent.
115
+ max_iterations (int): Maximum number of iterations for the agent to take.
116
+ early_stopping_method (str): Method to use for early stopping.
117
+ handle_parsing_errors (bool): Whether to handle parsing errors gracefully.
186
118
  """
187
119
  self.llm = ChatOpenAI(model=model)
188
120
  self.df = None
@@ -194,6 +126,10 @@ class PlotlyAgent:
194
126
  self.agent_executor = None
195
127
  self.generated_code = None
196
128
  self.system_prompt = system_prompt or DEFAULT_SYSTEM_PROMPT
129
+ self.verbose = verbose
130
+ self.max_iterations = max_iterations
131
+ self.early_stopping_method = early_stopping_method
132
+ self.handle_parsing_errors = handle_parsing_errors
197
133
 
198
134
  def set_df(self, df: pd.DataFrame, sql_query: Optional[str] = None):
199
135
  """
@@ -321,10 +257,10 @@ class PlotlyAgent:
321
257
  self.agent_executor = AgentExecutor(
322
258
  agent=agent,
323
259
  tools=tools,
324
- verbose=True,
325
- max_iterations=10,
326
- early_stopping_method="force",
327
- handle_parsing_errors=True,
260
+ verbose=self.verbose,
261
+ max_iterations=self.max_iterations,
262
+ early_stopping_method=self.early_stopping_method,
263
+ handle_parsing_errors=self.handle_parsing_errors,
328
264
  )
329
265
 
330
266
  def process_message(self, user_message: str) -> str:
plot_agent/models.py ADDED
@@ -0,0 +1,26 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+
4
+ # Define input schemas for the tools
5
+ class PlotDescriptionInput(BaseModel):
6
+ plot_description: str = Field(
7
+ ..., description="Description of the plot the user wants to create"
8
+ )
9
+
10
+
11
+ class GeneratedCodeInput(BaseModel):
12
+ generated_code: str = Field(
13
+ ..., description="Python code that creates a Plotly figure"
14
+ )
15
+
16
+
17
+ class DoesFigExistInput(BaseModel):
18
+ """Model indicating that the does_fig_exist function takes no arguments."""
19
+
20
+ pass
21
+
22
+
23
+ class ViewGeneratedCodeInput(BaseModel):
24
+ """Model indicating that the view_generated_code function takes no arguments."""
25
+
26
+ pass
plot_agent/prompt.py ADDED
@@ -0,0 +1,57 @@
1
+ DEFAULT_SYSTEM_PROMPT = """
2
+ You are an expert data visualization assistant that helps users create Plotly visualizations in Python.
3
+ Your job is to generate Python and Plotly code based on the user's request that will create the desired visualization
4
+ of their pandas DataFrame (df).
5
+
6
+ You have access to a pandas df with the following information:
7
+
8
+ df.info():
9
+ ```plaintext
10
+ {df_info}
11
+ ```
12
+
13
+ df.head():
14
+ ```plaintext
15
+ {df_head}
16
+ ```
17
+
18
+ {sql_context}
19
+
20
+ NOTES:
21
+ - You must use the execute_plotly_code(generated_code) tool run your code and use the does_fig_exist() tool to check that a fig object is available for display.
22
+ - You must paste the full code, not just a reference to the code.
23
+ - You must not use fig.show() in your code as it will ultimately be executed elsewhere in a headless environment.
24
+ - If you need to do any data cleaning or wrangling, do it in the code before generating the plotly code as preprocessing steps assume the data is in the pandas 'df' object.
25
+
26
+ TOOLS:
27
+ - execute_plotly_code(generated_code) to execute the generated code.
28
+ - does_fig_exist() to check that a fig object is available for display. This tool takes no arguments.
29
+ - view_generated_code() to view the generated code if need to fix it. This tool takes no arguments.
30
+
31
+ IMPORTANT CODE FORMATTING INSTRUCTIONS:
32
+ 1. Include thorough, detailed comments in your code to explain what each section does.
33
+ 2. Use descriptive variable names.
34
+ 3. DO NOT include fig.show() in your code - the visualization will be rendered externally.
35
+ 4. Ensure your code creates a variable named 'fig' that contains the Plotly figure object.
36
+
37
+ When a user asks for a visualization:
38
+ 1. YOU MUST ALWAYS use the execute_plotly_code(generated_code) tool to test and run your code.
39
+ 2. If there are errors, view the generated code using view_generated_code() and fix the code.
40
+ 3. Check that a figure object is available using does_fig_exist(). does_fig_exist() takes no arguments.
41
+ 4. If the figure object is not available, repeat the process until it is available.
42
+
43
+ IMPORTANT: The code you generate MUST be executed using the execute_plotly_code tool or no figure will be created!
44
+ YOU MUST CALL execute_plotly_code WITH THE FULL CODE, NOT JUST A REFERENCE TO THE CODE.
45
+
46
+ YOUR WORKFLOW MUST BE:
47
+ 1. execute_plotly_code(generated_code) to make sure the code is ran and a figure object is created.
48
+ 2. check that a figure object is available using does_fig_exist() to make sure the figure object was created.
49
+ 3. if there are errors, view the generated code using view_generated_code() to see what went wrong.
50
+ 4. fix the code and execute it again with execute_plotly_code(generated_code) to make sure the figure object is created.
51
+ 5. repeat until the figure object is available.
52
+
53
+ Always return the final working code (with all the comments) to the user along with an explanation of what the visualization shows.
54
+ Make sure to follow best practices for data visualization, such as appropriate chart types, labels, and colors.
55
+
56
+ Remember that users may want to iterate on their visualizations, so be responsive to requests for changes.
57
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plot-agent
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: An AI-powered data visualization assistant using Plotly
5
5
  Author-email: andrewm4894 <andrewm4894@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/andrewm4894/plot-agent
@@ -14,6 +14,9 @@ Dynamic: license-file
14
14
 
15
15
  # Plot Agent
16
16
 
17
+ [![Tests](https://github.com/andrewm4894/plot-agent/actions/workflows/test.yml/badge.svg)](https://github.com/andrewm4894/plot-agent/actions/workflows/test.yml)
18
+ [![PyPI version](https://badge.fury.io/py/plot-agent.svg)](https://badge.fury.io/py/plot-agent)
19
+
17
20
  An AI-powered data visualization assistant that helps users create Plotly visualizations in Python.
18
21
 
19
22
  ## Installation
@@ -26,12 +29,15 @@ pip install plot-agent
26
29
 
27
30
  ## Usage
28
31
 
29
- Here's a simple example of how to use Plot Agent:
32
+ See more examples in [/examples/](https://nbviewer.org/github/andrewm4894/plot-agent/tree/main/examples/) (via nbviewer so that can see the charts easily).
33
+
34
+ Here's a simple minimal example of how to use Plot Agent:
30
35
 
31
36
  ```python
32
37
  import pandas as pd
33
- from plot_agent.plotly_agent import PlotlyAgent
38
+ from plot_agent.agent import PlotlyAgent
34
39
 
40
+ # ensure OPENAI_API_KEY is set and available for langchain
35
41
 
36
42
  # Create a sample dataframe
37
43
  df = pd.DataFrame({
@@ -47,10 +53,45 @@ agent.set_df(df)
47
53
 
48
54
  # Process a visualization request
49
55
  response = agent.process_message("Create a line plot of x vs y")
56
+
57
+ # Print generated code
58
+ print(agent.generated_code)
59
+
60
+ # Get fig
50
61
  fig = agent.get_figure()
51
62
  fig.show()
52
63
  ```
53
64
 
65
+ `agent.generated_code`:
66
+
67
+ ```python
68
+ import pandas as pd
69
+ import plotly.graph_objects as go
70
+
71
+ # Creating a line plot of x vs y
72
+ # Create a figure object
73
+ fig = go.Figure()
74
+
75
+ # Add a line trace to the figure
76
+ fig.add_trace(
77
+ go.Scatter(
78
+ x=df['x'], # The x values
79
+ y=df['y'], # The y values
80
+ mode='lines+markers', # Display both lines and markers
81
+ name='Line Plot', # Name of the trace
82
+ line=dict(color='blue', width=2) # Specify line color and width
83
+ )
84
+ )
85
+
86
+ # Adding titles and labels
87
+ fig.update_layout(
88
+ title='Line Plot of x vs y', # Plot title
89
+ xaxis_title='x', # x-axis label
90
+ yaxis_title='y', # y-axis label
91
+ template='plotly_white' # A clean layout
92
+ )
93
+ ```
94
+
54
95
  ## Features
55
96
 
56
97
  - AI-powered visualization generation
@@ -0,0 +1,9 @@
1
+ plot_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ plot_agent/agent.py,sha256=zukHGVexMXOHHjtmb7dNB3l2iEpC0rq0a6UUpVPLe14,10845
3
+ plot_agent/models.py,sha256=ZOWWeYaqmnKJarXYyXnBQQ4nwUe71ae_gMul3bZXaWU,644
4
+ plot_agent/prompt.py,sha256=HjRgbsAe8HHs8arQogvzOGQdThEWKRqQhtQyaUplxhQ,3064
5
+ plot_agent-0.2.0.dist-info/licenses/LICENSE,sha256=A4DPih7wHrh4VMEG3p1PhorqdhjmGIo8nQdYNQL7daA,1062
6
+ plot_agent-0.2.0.dist-info/METADATA,sha256=1_3wlHu5E1_gONv4uckGTc4X9F7hHzXuQRv9EjAHIVI,2841
7
+ plot_agent-0.2.0.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
8
+ plot_agent-0.2.0.dist-info/top_level.txt,sha256=KyOjpihUssx26Ra-37vKUQ71pI2qgJsHaRwXHJUhjzQ,11
9
+ plot_agent-0.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (78.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,7 +0,0 @@
1
- plot_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- plot_agent/plotly_agent.py,sha256=93DSwnPU7_915nsXs8SIUuL1hXFTEozBaqWQxs4HM9Y,13637
3
- plot_agent-0.1.2.dist-info/licenses/LICENSE,sha256=A4DPih7wHrh4VMEG3p1PhorqdhjmGIo8nQdYNQL7daA,1062
4
- plot_agent-0.1.2.dist-info/METADATA,sha256=GddWhRuPQ3DpujQGTANyk22oMsMASmZ2bdjz9CkZfdc,1589
5
- plot_agent-0.1.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
6
- plot_agent-0.1.2.dist-info/top_level.txt,sha256=KyOjpihUssx26Ra-37vKUQ71pI2qgJsHaRwXHJUhjzQ,11
7
- plot_agent-0.1.2.dist-info/RECORD,,