This document is a guided walkthrough of the “Persona Based Dashboards” tutorial App. In this App, we demonstrate how the Virtualitics AI Platform (VAIP) can be used to create hyper-personalized dashboards that meet the unique needs of any end user.
In this tutorial, we are creating dashboards that present insights on invoice data for a UK-based e-commerce company.
If you want to review the App in use while also reviewing the code, you can download the code and use the Command Line Interface (CLI) to deploy this App in the VAIP and progress through it as you follow this walkthrough. For more on using the CLI to deploy an App, see this article.
The data for this walkthrough can also be found at the bottom of this page and was sourced from Kaggle.
If this is your first introduction to developing for the VAIP, also consider the “Hello World!” tutorial App. It is our beginner level tutorial App and primarily focuses on the core aspects of App development.
Constructing the App
When creating App scripts, we recommend organizing your file in the following order:
-
Imports
-
Step Definitions
-
App and Pages Creation
This sequential organization can be seen in the full script for this App, provided as a download below. However, for the purpose of this walkthrough, we will go through each Step and its corresponding Page together.
Imports
Every App begins by importing the key classes, which include Card, Section, Page, and Step. It is also important to import the various Elements to be used.
You will also need to import:
-
Element and plot types from the Virtualitics SDK
-
Packages you’ll use for data processing, such as NumPy and Pandas
# Import Virtualitics AI Application internal elements
from virtualitics_sdk import (
App, Step, StepType, Page, Section, Card, StoreInterface, InfographData, Infographic,
InfographicOrientation, CustomEvent, DataSource, Image, Table, ImageSize, Column, Row,
InfographDataType, Dropdown, DateTimeRange, PlotlyPlot
)
# Import external packages
import plotly.express as px
from PIL import Image as PILImage
from io import BytesIO
import pandas as pd
import string
Building the App
Steps are the primary building blocks of a App. They orchestrate all backend and frontend tasks performed on each page. We will now go through each of this App's Steps and their corresponding Pages:
-
Data Upload
-
Executive Dashboard
-
Operational Dashboard
1. Data Upload
This first Step uses the DataSource Element to provide the user with a means of uploading data. It is added to a Card and then placed into a Section, all of which displays on a Page, fetched using StoreInterface
.
This Step also includes a specification that the data must be uploaded as a CSV file and provides additional information to help guide the user.
# This step has the user upload the dataset we'll be using
class DataUploadStep(Step):
def run(self, flow_metadata):
store_interface = StoreInterface(**flow_metadata)
page = store_interface.get_page()
data_source_link = "https://docs.virtualitics.com/hc/en-us/articles/34931990206099"
data_source_description = (
f"You can find the relevant data for this tutorial here: {data_source_link}"
)
data_source = DataSource(
title="Upload e-commerce data here!",
options=["csv"],
description=data_source_description,
required=True,
)
data_card = Card(title="Data Upload Card", content=[data_source])
page.add_card_to_section(data_card, "")
store_interface.update_page(page)
Altogether, this creates a Page which prompts the user to upload specified e-commerce data in CSV format.
2. Executive Dashboard
Here, the uploaded data is used to calculate high-level insights. Those insights are then displayed in a Dashboard.
Data Import and Cleaning
This Step begins by pulling in the uploaded data from the previous Step’s DataSource Element. Next, the Step runs cleaning and preprocessing and then saves the data as an Asset. This persists the data in the user’s VAIP workspace and allows them to access it at any time.
# Get the data from the data upload step, turn it into an asset to persist it for later use
df = store_interface.get_element_value(
data_upload_step.name, "Upload e-commerce data here!"
)
df["SaleValue"] = df["Quantity"] * df["UnitPrice"]
df["InvoiceDate"] = pd.to_datetime(df["InvoiceDate"])
df["InvoiceMonth"] = df["InvoiceDate"].dt.strftime("%Y-%m")
df["Description"] = df["Description"].apply(lambda x: string.capwords(str(x)))
store_interface.save_output(df, "Predict Data")
Producing a Line Plot with Key Insights
Next, insights are calculated and visualized with various Elements, according to the user’s needs.
The code below produces a Plotly plot of total sales revenue by month.
# Calculate the total sales for each month and create a line plot
sales_by_month = df.groupby("InvoiceMonth").agg(
TotalSalesValue=("SaleValue", "sum")
)
sales_by_month = (
sales_by_month.sort_values("InvoiceMonth", ascending=True)
.reset_index(level=0)
.head(-1)
)
# Create the line plot
sales_by_month_fig = px.line(
sales_by_month,
x="InvoiceMonth",
y="TotalSalesValue",
title="Total Sales Revenue by Month",
labels={"InvoiceMonth": "Invoice Month", "TotalSalesValue": "Total Sales Revenue"},
markers=True,
template="predict_default"
)
sales_by_month_line = PlotlyPlot(sales_by_month_fig)
Adding an Insight-Rich Infographic
In addition to the Plot, an insight-rich Infographic is created.
# Get current month recurring clients
current_sales_by_client_month = sales_by_client_month[
sales_by_client_month.InvoiceMonth
== sales_by_client_month.InvoiceMonth.max()
]
current_clients_count = current_sales_by_client_month.shape[0]
recurring_customers_ratio = (
current_sales_by_client_month["PreviousMonthSales"].count()
/ current_clients_count
* 100
)
# Get products sold consistently over time
consistently_sold_products = (
sales_value_by_product.sort_values("MonthsSoldFor", ascending=False)
.head(2)
.reset_index(level=0)
)
# Get products sold in highest quantities
high_quantity_sold_products = (
sales_value_by_product.sort_values("TotalQuantitySold", ascending=False)
.head(2)
.reset_index(level=0)
)
# Calculate the total sales value for this calendar year
current_year = df["InvoiceDate"].dt.year.max()
ytd_rev = df[df["InvoiceDate"].dt.year == current_year]["SaleValue"].sum()
# Create the InfographData elements needed and attach them to the Infographic
executive_info_blocks = [
InfographData(
label="Recurring Customers",
main_text=f"{int(recurring_customers_ratio)}%",
supporting_text="of customers are retained month-to-month",
icon="check_circle",
_type=InfographDataType.POSITIVE,
),
InfographData(
label="Consistently Sold Products",
main_text=", ".join(list(consistently_sold_products["Description"])),
supporting_text="products with the most recurring sales",
icon="warning",
_type=InfographDataType.WARNING,
),
InfographData(
label="Highest Quantity Sold",
main_text=", ".join(list(high_quantity_sold_products["Description"])),
supporting_text="products with the highest logistic load",
icon="check_circle",
_type=InfographDataType.POSITIVE,
),
InfographData(
label="YTD Revenue",
main_text=f"${ytd_rev:,.0f}",
supporting_text="generated this year",
icon="info",
_type=InfographDataType.INFO,
),
]
executive_info = Infographic(
title="Insights on Revenue Growth Opportunities",
description="All information is derived " + "from the past year of data",
data=executive_info_blocks,
layout=InfographicOrientation.ROW,
)
Altogether, this Step creates a Card with both a Plot and Infographic layout.
top_row = Row([Column([top_products_bar], ratio=[0.7]), Column([non_uk_buyers_bar], ratio=[0.7])])
bottom_row = Row([table, Column([sales_by_month_line], ratio=[0.7])])
# Create a Dashboard using the previously created columns, add it to the current page and persist the changes
executive_card = Card(
title="Executive Dashboard Plots",
content=[executive_info, top_row, bottom_row],
show_title=False,
filters=[date_range_element, country_selection],
filter_update=ExecutiveUpdater,
)
current_page.add_card_to_section(executive_card, "Simple Dash")
3. Operational Dashboard
This Step is similar to the previous one. The uploaded data is used to calculate high-level insights and those insights are then displayed in a Dashboard.
However, this Page focuses on more recent invoice information and actions that can be taken to capitalize upon it.
In addition to an insight-rich Dashboard, also included is a "Recommendation" infographic that allows the user to run a CustomEvent.
# Create a Recommendation Infographic
rec = InfographData(
label="Recommended Action",
main_text="**Kick-off segmentation based marketing campaign?**",
supporting_text="Additional text can be placed here",
icon="info",
_type=InfographDataType.POSITIVE,
)
kick_off_event = KickOffEvent(
"Kick-off", "Would you like to take the recommended action?"
)
info_rec = Infographic(
title="Insights and Recommended Action",
description="Suggested action based on model predictions",
recommendation=[rec],
layout=InfographicOrientation.ROW,
event=kick_off_event,
)
This produces a Recommendation infographic with a prompt for action.
Creating the App Object
Here, the actual App object is created and an image is assigned to be associated with it on the VAIP Home Page.
# Instantiate flow and assign image
image_link = "https://predict-tutorials.s3-us-gov-west-1.amazonaws.com/persona_based_dashboards_tile.jpeg"
persona_dashboards = App(
name="Persona Based Dashboard",
description="New to writing flows in Predict?" + " Check out this tutorial flow.",
image_path=image_link,
)
If set up successfully, this will show the App and the relevant tile image on the VAIP Home Page once the App has been uploaded.
Completing an App
The final step in constructing an App involves chaining together each Step in the App Object that was created at the start.
To do this, an ordered list of the Steps is passed to the App's chain()
method.
# Chain together the steps of the app
persona_dashboards.chain([data_upload_step, simple_dashboards_step, data_explore_step])
Deploying an App
After completing this final step, the App file can be deployed to the VAIP using the CLI. For more on using the CLI to deploy this App, see this article.
Previous Article |
Next Article |