Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
nadijagraca committed Sep 18, 2024
2 parents f94fe52 + 0824a20 commit 43a45ff
Show file tree
Hide file tree
Showing 64 changed files with 740 additions and 722 deletions.
Binary file added .github/images/visual_vocabulary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .github/images/vizro_examples_gallery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions .github/workflows/vizro-qa-tests-trigger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
include:
- label: integration tests
- label: notebooks tests
- label: vizro-ai ui tests
steps:
- name: Passed fork step
run: echo "Success!"
Expand All @@ -36,6 +37,7 @@ jobs:
include:
- label: integration tests
- label: notebooks test
- label: vizro-ai ui tests
steps:
- uses: actions/checkout@v4
- name: Tests trigger
Expand All @@ -46,6 +48,8 @@ jobs:
export INPUT_WORKFLOW_FILE_NAME=${{ secrets.VIZRO_QA_INTEGRATION_TESTS_WORKFLOW }}
elif [ "${{ matrix.label }}" == "notebooks test" ]; then
export INPUT_WORKFLOW_FILE_NAME=${{ secrets.VIZRO_QA_NOTEBOOKS_TESTS_WORKFLOW }}
elif [ "${{ matrix.label }}" == "vizro-ai ui tests" ]; then
export INPUT_WORKFLOW_FILE_NAME=${{ secrets.VIZRO_QA_VIZRO_AI_UI_TESTS_WORKFLOW }}
fi
export INPUT_GITHUB_TOKEN=${{ secrets.VIZRO_SVC_PAT }}
export INPUT_REF=main # because we should send existent branch to dispatch workflow
Expand Down
3 changes: 1 addition & 2 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
* @Joseph-Perkins @antonymilne @huong-li-nguyen @maxschulz-COL
vizro-ai/ @Joseph-Perkins @Anna-Xiong @lingyielia @maxschulz-COL
* @Joseph-Perkins @antonymilne @huong-li-nguyen @maxschulz-COL @lingyielia
docs/ @stichbury @Joseph-Perkins @antonymilne @huong-li-nguyen @maxschulz-COL
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Optional high-code extensions enable almost infinite customization in a modular

Visit ["Why should I use Vizro?"](https://vizro.readthedocs.io/en/stable/pages/explanation/faq/#why-should-i-use-vizro) for a more detailed explanation of Vizro use cases.

### What is Vizro-AI?
## What is Vizro-AI?

Vizro-AI is a separate package and extends Vizro to enable the use of natural language queries to build Plotly charts.

Expand All @@ -102,10 +102,19 @@ See the [Vizro-AI documentation](https://vizro.readthedocs.io/projects/vizro-ai/

You can see Vizro in action by clicking on the following image or by visiting [the examples gallery at vizro.mckinsey.com](https://vizro.mckinsey.com).

<p align="left">
<a href="http://vizro.mckinsey.com/">
<img border="0" src="https://raw.githubusercontent.com/mckinsey/vizro/main/.github/images/vizro_examples_gallery.png" width="525" height="296"> </a>
</p>
<img src="https://raw.githubusercontent.com/mckinsey/vizro/main/.github/images/vizro_examples_gallery.png" width="550">
</a>

## Vizro visual vocabulary

Our visual vocabulary dashboard helps you to select and create various types of charts. It helps you decide when to use
each chart type, and offers sample Python code to create these charts with [Plotly](https://plotly.com/python/) and
embed them into a Vizro dashboard.

<a href="https://huggingface.co/spaces/vizro/demo-visual-vocabulary/">
<img src="https://raw.githubusercontent.com/mckinsey/vizro/main/.github/images/visual_vocabulary.png" width="550">
</a>

## Dashboard screenshots

Expand Down
16 changes: 16 additions & 0 deletions vizro-ai/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ See the fragment files in the [changelog.d directory](https://github.com/mckinse

<!-- scriv-insert-here -->

<a id='changelog-0.2.3'></a>

# 0.2.3 — 2024-09-09

## Added

- Added Docker image of `VizroAI.plot` UI for local use ([#1177](https://github.com/mckinsey/vizro/pull/1177))

<a id='changelog-0.2.2'></a>

# 0.2.2 — 2024-09-06

## Fixed

- Documented the step for instantiating `VizroAI` in text-to-dashboard pages ([#685](https://github.com/mckinsey/vizro/pull/685))

<a id='changelog-0.2.1'></a>

# 0.2.1 — 2024-08-28
Expand Down

This file was deleted.

43 changes: 37 additions & 6 deletions vizro-ai/docs/pages/tutorials/quickstart-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,14 @@ print(vizro_ai.__version__)

You should see a return output of the form `x.y.z`.

## 3. Instantiate VizroAI
```py
from vizro_ai import VizroAI

vizro_ai = VizroAI()
```

## 3. Prepare the data
## 4. Prepare the data
Next, prepare the data to pass to Vizro-AI. In this example, we use the [gapminder data](https://plotly.com/python-api-reference/generated/plotly.express.data.html#plotly.express.data.gapminder).

```py
Expand All @@ -52,7 +58,7 @@ import vizro.plotly.express as px
df = px.data.gapminder(datetimes=True, pretty_names=True)
```

## 4. Prepare the user prompt
## 5. Prepare the user prompt

Put together a string of text which is the prompt to request Vizro-AI to generate the dashboard.

Expand All @@ -65,7 +71,7 @@ Vizro-AI can generate a multi-page dashboard that includes the following feature

```text
user_question = """
Create a page showing 1 card, 1 chart, and 1 filter.
Create a page showing 1 card, 1 chart.
The first card says 'The Gapminder dataset is a detailed collection of global socioeconomic indicators over several decades. It includes data on GDP per capita, life expectancy, and population for numerous countries and regions. This dataset allows users to analyze development trends, health outcomes, economic growth, and demographic changes globally.'
The chart is a box plot showing life expectancy distribution. Put Life expectancy on the y axis, continent on the x axis, and color by continent.
The card takes 1 grid of the page space on the left and the box plot takes 3 grid space on the right.
Expand All @@ -74,20 +80,45 @@ Add a filter to filter the box plot by year.
"""
```

## 5. Call Vizro-AI
## 6. Call Vizro-AI

Next, submit the data and prompt string:

```py
dashboard = vizro_ai._dashboard([df], user_question)
```

The call to `_dashboard()` triggers the dashboard building process. Once Vizro-AI finishes the dashboard generation process, you can launch the dashboard with `build()`.
The call to `_dashboard()` initiates dashboard generation. By default, it generates the Vizro `Dashobard` Object.

## 7. Build dashboard
Once dashboard generation is complete, launch the dashboard with `build()`.

```py
from vizro import Vizro
Vizro().build(dashboard).run()
```

!!! example "Generated dashboard"

=== "Code"
=== "Code for the cell"
```py
from vizro import Vizro
from vizro_ai import VizroAI
import vizro.plotly.express as px

df = px.data.gapminder(datetimes=True, pretty_names=True)
vizro_ai = VizroAI()

user_question = """
Create a page showing 1 card and 1 chart.
The first card says 'The Gapminder dataset is a detailed collection of global socioeconomic indicators over several decades. It includes data on GDP per capita, life expectancy, and population for numerous countries and regions. This dataset allows users to analyze development trends, health outcomes, economic growth, and demographic changes globally.'
The chart is a box plot showing life expectancy distribution. Put Life expectancy on the y axis, continent on the x axis, and color by continent.
The card takes 1 grid of the page space on the left and the box plot takes 3 grid space on the right.

Add a filter to filter the box plot by year.
"""

dashboard = vizro_ai._dashboard([df], user_question)
Vizro().build(dashboard).run()
```

Expand Down
3 changes: 3 additions & 0 deletions vizro-ai/docs/pages/user-guides/create-complex-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ It's worth noting that a more structured user request is also more machine reada
Next, submit the data and prompt string:

```py
from vizro_ai import VizroAI

vizro_ai = VizroAI(model="gpt-4o")
dashboard = vizro_ai._dashboard([df1, df2], user_question)
```

Expand Down
3 changes: 3 additions & 0 deletions vizro-ai/docs/pages/user-guides/retrieve-dashboard-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Create a one-page dashboard layout with the following components:

## 2. Generate and launch the dashboard
```py
from vizro_ai import VizroAI

vizro_ai = VizroAI(model="gpt-4o-mini")
result = vizro_ai._dashboard([df], user_question, return_elements=True)
```
This will trigger the dashboard building process. Once Vizro-AI finishes the dashboard generation process, you can now launch the dashboard.
Expand Down
41 changes: 41 additions & 0 deletions vizro-ai/examples/dashboard_ui/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Git
.git
.gitignore
.gitattributes

# Docker
Dockerfile
docker-compose.yml
.dockerignore

# Python
*.pyc
*.pyo
*.pyd
__pycache__
.pytest_cache
.coverage
htmlcov/
.tox/
.venv
venv/
*.egg-info/
dist/
build/

# Editors
.vscode/
.idea/
*.swp
*.swo

# OS generated
.DS_Store
Thumbs.db

# Application specific
*.log
*.sqlite3

# csv
*.csv
37 changes: 37 additions & 0 deletions vizro-ai/examples/dashboard_ui/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM python:3.12-slim AS builder

RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
WORKDIR $HOME/app

COPY --chown=user requirements.txt .
RUN pip install --user --no-cache-dir --upgrade pip && \
pip install --user --no-cache-dir -r requirements.txt

# Production stage
FROM python:3.12-slim

RUN apt-get update && apt-get upgrade -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
WORKDIR $HOME/app

COPY --from=builder --chown=user $HOME/.local/lib/python3.12/site-packages $HOME/.local/lib/python3.12/site-packages
COPY --from=builder --chown=user $HOME/.local/bin $HOME/.local/bin

COPY --chown=user . $HOME/app

EXPOSE 7860

CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:7860", "app:server"]
11 changes: 11 additions & 0 deletions vizro-ai/examples/dashboard_ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Vizro Ai UI
emoji: 🌖
colorFrom: blue
colorTo: pink
sdk: docker
pinned: false
license: apache-2.0
---

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
10 changes: 8 additions & 2 deletions vizro-ai/examples/dashboard_ui/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
from vizro.models.types import capture
from vizro_ai import VizroAI

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO) # TODO: remove manual setting and make centrally controlled

SUPPORTED_VENDORS = {"OpenAI": ChatOpenAI}


Expand Down Expand Up @@ -62,6 +65,7 @@ def create_response(ai_response, figure, user_prompt, filename):
return create_response(ai_response, figure, user_prompt, data["filename"])

try:
logger.info("Attempting chart code.")
df = pd.DataFrame(data["data"])
ai_outputs = get_vizro_ai_plot(
user_prompt=user_prompt,
Expand All @@ -76,10 +80,12 @@ def create_response(ai_response, figure, user_prompt, filename):
formatted_code = black.format_str(ai_code, mode=black.Mode(line_length=100))

ai_response = "\n".join(["```python", formatted_code, "```"])
logger.info("Successful query produced.")
return create_response(ai_response, figure, user_prompt, data["filename"])

except Exception as exc:
logging.exception(exc)
logger.debug(exc)
logger.info("Chart creation failed.")
ai_response = f"Sorry, I can't do that. Following Error occurred: {exc}"
figure = go.Figure()
return create_response(ai_response, figure, user_prompt, data["filename"])
Expand Down Expand Up @@ -109,7 +115,7 @@ def data_upload_action(contents, filename):
return {"data": data, "filename": filename}

except Exception as e:
logging.exception(e)
logger.debug(e)
return {"error_message": "There was an error processing this file."}


Expand Down
Loading

0 comments on commit 43a45ff

Please sign in to comment.