Home Artificial Intelligence The Ultimate Visualization Assistant

The Ultimate Visualization Assistant

0
The Ultimate Visualization Assistant

How a night with AI transformed my approach to visualizing data

Photo by Simon Abrams on Unsplash

Because the sun began to dim and the town lights got here to life, the inevitability of a late night within the office settled in. I discovered myself in a race against time. An important sales presentation was looming lower than a day away, and success hinged on an unfulfilled request — an insightful data visualization that would succinctly convey the underlying methodology of our recent TV attribution model.

I needed something complex enough to point out off, but easy enough to convey most of the data without explanation. Not a straightforward task with a ticking clock. Thankfully, a beacon of artificial intelligence, my trusty recent assistant — ChatGPT — sat able to simplify the duty at hand. Its important mission: To assist me translate data that was not more than an idea in my head into an eloquent visual narrative, able to fascinating even probably the most data-averse minds within the room.

This could be somewhat high drama, but I was in a little bit of a crunch. For a sales deck, this needed an excessively easy example which I couldn’t readily find in our database, so made-up example data it was.

I knew in my head exactly what I desired to display — an online traffic baseline, a spike in web responses following a TV ad, and a few approach to convey in little to no words that in this instance we’d attribute the difference between the baseline and the spike.

Matplotlib charts are solid in an instructional paper but can require an excessively deft hand to provide something each complex and truly flashy. I often turn to Power BI for the out-of-the-box looks and quick charts, but it surely isn’t ideal to work with when you should formulate something from scratch with no existing data.

I’d been working with Plotly for some time, which gave the look of a completely satisfied medium. Nonetheless, I wasn’t confident enough with the package to place my thoughts into code without spending precious minutes combing through documentation and Stack Overflow. So, with time short, I began my first prompt.

I’m making a visualization to display web traffic response following a TV spot airing. Let’s start by representing web traffic as a per minute count of site visits over the course of half-hour. The primary ten minutes should be a random number between 0 and 4. The second ten minute period must be random numbers between 4 and 20, with the numbers distributed in what looks like a right skewed histogram. The third ten minute period is similar as the primary ten minute period. Please create that data and chart it for me using a line graph in Plotly.

The prompt returned the next, with my only edits within the update_layout function:

import numpy as np
import plotly.graph_objects as go

# Set seed for reproducibility
np.random.seed(42)

# Create arrays with the required distributions
first_ten = np.random.uniform(low=0, high=4, size=10)
last_ten = np.random.uniform(low=0, high=4, size=10)
middle_ten = np.random.gamma(shape=2, scale=2, size=10) + 4 # shift the gamma distribution

# Mix the arrays
measurements = np.concatenate((first_ten, middle_ten, last_ten))

# Create x values
x_values = np.arange(1, 31)

# Create the road chart
fig = go.Figure(
data=go.Scatter(
x=x_values,
y=measurements,
mode='lines+markers')
)

fig.update_layout(
title='Ad Influence on Web Traffic',
xaxis_title='Time',
yaxis_title='Visits per Minute',
width=1000,
height=600
)

fig.show()

Chart as generated by the prior code block

I used to be already impressed here as I wasn’t expecting the right-skewed histogram lookalike request to be handled so well. Possibly I’d even be finished before the after-work session down the block was over.

Next, I needed something to represent the net traffic baseline. In point of fact, this could possibly be so simple as a rolling median, but asking for that here won’t work with the limited length of information. As a substitute, I figured the median of the primary and third sets of ten observations would probably convey the correct idea.

Please calculate the combined median of the 2 arrays first_ten and last_ten. Plot the calculated median as a continuing horizontal line.

import numpy as np
import plotly.graph_objects as go

# Set seed for reproducibility
np.random.seed(42)

# Create arrays with the required distributions
first_ten = np.random.uniform(low=0, high=4, size=10)
last_ten = np.random.uniform(low=0, high=4, size=10)
middle_ten = np.random.gamma(shape=2, scale=2, size=10) + 4 # shift the gamma distribution

# Mix the arrays
measurements = np.concatenate((first_ten, middle_ten, last_ten))

# Create x values
x_values = np.arange(1, 31)

# Calculate combined median
combined_median = np.median(np.concatenate((first_ten, last_ten)))

# Create the road chart
fig = go.Figure()

# Create the road chart
fig = go.Figure(
data=go.Scatter(
x=x_values,
y=measurements,
mode='lines+markers')
)

# Add median line
fig.add_trace(
go.Scatter(
x=x_values,
y=[combined_median]*len(x_values),
mode='lines',
name='Baseline',
line=dict(color='firebrick', width=2, dash='dash'))
)

fig.update_layout(
title='Ad Influence on Web Traffic',
xaxis_title='Time',
yaxis_title='Visits per Minute',
width=1000,
height=600
)

fig.show()

I then just modified the name of the median line trace from “Median” to “Baseline”.

Chart from the above code block, which added the baseline constant line

Now the concept of “lift” comes through in case you’re accustomed to marketing models, nevertheless, for the untrained eye this needs some more focused elements; the less that needs explaining, the simpler a visible is. The important things missing at this point were a chart element that means causality of the spike in web traffic, and a approach to convey the quantity of traffic attributed to the ad.

I began with the causality element.

At minute 10 in the information, a TV spot airs and drives a spike in web traffic. What type of chart element would you suggest to convey not only that the ad ran that minute, but that the ad is the causal factor behind the spike?

The response suggested a vertical line and annotation and provided the code update.

import numpy as np
import plotly.graph_objects as go

# Set seed for reproducibility
np.random.seed(42)

# Create arrays with the required distributions
first_ten = np.random.uniform(low=0, high=4, size=10)
last_ten = np.random.uniform(low=0, high=4, size=10)
middle_ten = np.random.gamma(shape=2, scale=2, size=10) + 4 # shift the gamma distribution

# Mix the arrays
measurements = np.concatenate((first_ten, middle_ten, last_ten))

# Create x values
x_values = np.arange(1, 31)

# Calculate combined median
combined_median = np.median(np.concatenate((first_ten, last_ten)))

# Create the road chart
fig = go.Figure()

# Add scatter plot
fig.add_trace(
go.Scatter(
x=x_values,
y=measurements,
mode='lines+markers',
name='Web Traffic')
)

# Add median line
fig.add_trace(
go.Scatter(
x=x_values,
y=[combined_median]*len(x_values),
mode='lines',
name='Baseline',
line=dict(color='firebrick', width=2, dash='dash'))
)

# Add vertical line at minute 10
fig.add_shape(
type='line',
x0=10, y0=0,
x1=10, y1=max(measurements),
line=dict(
color="Purple",
width=3,
dash="dot",
)
)

# Add annotation to point TV spot
fig.add_annotation(
x=10,
y=max(measurements),
text="TV ad aired",
showarrow=True,
arrowhead=1,
ax=-100,
ay=-25,
font=dict(
size=16,
color="Black"
),
)

fig.update_layout(
title='Ad Influence on Web Traffic',
xaxis_title='Time',
yaxis_title='Visits per Minute',
width=1000,
height=600
)

fig.show()

I modified only the font size of the annotation.

Chart from the above code block, which added the TV ad aired constant line and annotation

Now we had a clearly defined cause and point of occurrence for the spike. The chart still needed something to indicate the quantity of traffic attributed. I already knew what I wanted for this — to shade the world between the baseline and web traffic throughout the “lift window” (ten minutes). I went back to my AI colleague to implement this.

I would like to display the quantity of web traffic above baseline that’s attributed to the ad. Please add green shading between the baseline line and web traffic per minute line. Only shade the world between the tenth and twentieth minute of the information. Also add a legend item for the shaded area.

import numpy as np
import plotly.graph_objects as go

# Set seed for reproducibility
np.random.seed(42)

# Create arrays with the required distributions
first_ten = np.random.uniform(low=0, high=4, size=10)
last_ten = np.random.uniform(low=0, high=4, size=10)
middle_ten = np.random.gamma(shape=2, scale=2, size=10) + 4 # shift the gamma distribution

# Mix the arrays
measurements = np.concatenate((first_ten, middle_ten, last_ten))

# Create x values
x_values = np.arange(1, 31)

# Calculate combined median
combined_median = np.median(np.concatenate((first_ten, last_ten)))

# Create the road chart
fig = go.Figure()

# Add scatter plot
fig.add_trace(
go.Scatter(
x=x_values,
y=measurements,
mode='lines+markers',
name='Web Traffic')
)

# Add median line
fig.add_trace(
go.Scatter(
x=x_values,
y=[combined_median]*len(x_values),
mode='lines',
name='Baseline',
line=dict(color='firebrick', width=2, dash='dash'))
)

# Add shaded region for the influence of the ad
fig.add_trace(
go.Scatter(
x=list(x_values[9:20]) + list(x_values[9:20])[::-1],
y=list([combined_median]*11) + list(measurements[9:20])[::-1],
fill='toself',
fillcolor='rgba(0,200,0,0.2)',
line=dict(width=0),
hoverinfo="skip",
showlegend=True,
name='Ad Impact')
)

# Add vertical line at minute 10
fig.add_shape(
type='line',
x0=10, y0=0,
x1=10, y1=max(measurements),
line=dict(
color="Purple",
width=3,
dash="dot",
)
)

# Add annotation to point TV spot
fig.add_annotation(
x=10,
y=max(measurements),
text="TV ad aired",
showarrow=True,
arrowhead=1,
ax=-100,
ay=-25,
font=dict(
size=16,
color="Black"
),
)

fig.update_layout(
title='Ad Influence on Web Traffic',
xaxis_title='Time',
yaxis_title='Visits per Minute',
width=1000,
height=600
)

fig.show()

Chart from the above code block, which added the shading to represent ad impact

I felt like this was attending to a great place, but I still wasn’t completely satisfied with the “clarity” of what I used to be attempting to convey. I made some additions based on the code I’d already been given.

I added a continuing vertical line and annotation to indicate the lift window cutoff, and adjusted the colours of the ad aired and window cutoff lines to green and red, respectively. I also modified the baseline constant line to purple and styled it as dotted to higher match the opposite constant lines.

I then wanted one final element — shading for the baseline region. Wanting to tap the stainless performance to date, I gave this one to my assistant.

Please add purple shading to your complete baseline region. Add an annotation saying “Baseline” at minute 15, underneath the baseline constant horizontal line.

Note here that I haven’t referenced any coordinates or specific numbers for the situation of the shading.

import numpy as np
import plotly.graph_objects as go

# Set seed for reproducibility
np.random.seed(42)

# Create arrays with the required distributions
first_ten = np.random.uniform(low=0, high=4, size=10)
last_ten = np.random.uniform(low=0, high=4, size=10)
middle_ten = np.random.gamma(shape=2, scale=2, size=10) + 4 # shift the gamma distribution

# Mix the arrays
measurements = np.concatenate((first_ten, middle_ten, last_ten))

# Create x values
x_values = np.arange(1, 31)

# Calculate combined median
combined_median = np.median(np.concatenate((first_ten, last_ten)))

# Create the road chart
fig = go.Figure()

# Add baseline region
fig.add_trace(
go.Scatter(
x=list(x_values) + list(x_values)[::-1],
y=[combined_median]*len(x_values) + [0]*len(x_values),
fill='toself',
fillcolor='rgba(128, 0, 128, 0.2)',
line=dict(width=0),
hoverinfo="skip",
showlegend=True,
name='Baseline')
)

# Add scatter plot
fig.add_trace(
go.Scatter(
x=x_values,
y=measurements,
mode='lines+markers',
name='Web Traffic',
line=dict(color='#636EFA'))
)

# Add median line
fig.add_trace(
go.Scatter(
x=x_values,
y=[combined_median]*len(x_values),
mode='lines',
name='Median',
line=dict(color='Purple', width=2, dash='dash'))
)

# Add shaded region for the influence of the ad
fig.add_trace(
go.Scatter(
x=list(x_values[9:20]) + list(x_values[9:20])[::-1],
y=list([combined_median]*11) + list(measurements[9:20])[::-1],
fill='toself',
fillcolor='rgba(0,200,0,0.2)',
line=dict(width=0),
hoverinfo="skip",
showlegend=True,
name='Ad Impact')
)

# Add vertical line at minute 10
fig.add_shape(
type='line',
x0=10, y0=0,
x1=10, y1=max(measurements),
line=dict(
color="Green",
width=3,
dash="dot",
)
)

# Add annotation to point TV spot
fig.add_annotation(
x=10,
y=max(measurements),
text="TV ad aired",
showarrow=True,
arrowhead=1,
ax=-100,
ay=-25,
font=dict(
size=16,
color="Green"
),
)

# Add vertical line at minute 20
fig.add_shape(
type='line',
x0=20, y0=0,
x1=20, y1=max(measurements),
line=dict(
color="Red",
width=3,
dash="dot",
)
)

# Add annotation to point lift window cutoff
fig.add_annotation(
x=20,
y=max(measurements),
text="Lift window cutoff",
showarrow=True,
arrowhead=1,
ax=100,
ay=-25,
font=dict(
size=16,
color="Red"
),
)

# Add annotation for lift
fig.add_annotation(
x=15,
y=combined_median + (max(measurements[9:20])-combined_median)/4,
text="Lift because of Ad",
showarrow=False,
font=dict(
size=18,
color="Green"
),
)

# Add annotation for baseline
fig.add_annotation(
x=15,
y=combined_median/2,
text="Baseline",
showarrow=False,
font=dict(
size=18,
color="Purple"
),
)

fig.update_layout(
title='Ad Influence on Web Traffic',
xaxis_title='Time',
yaxis_title='Visits per Minute',
width=1000,
height=600
)

fig.show()

Chart from the above code block, which added baseline shading, a cutoff line, and more annotations

The capture of the baseline shading request without being provided specific values is top-tier, and at this point, I used to be beyond impressed. Blissful with the visualization, I dropped the chart into the presentation, fired off a Teams message, and with a fond take a look at the ChatGPT tab, closed my laptop. As I used to be packing up, a notification from the after-work group chat flashed across my phone screen.

Saw the presentation message, thought you said you’d be going late? We’ll have a pint waiting for you.

Cheers, ChatGPT.

LEAVE A REPLY

Please enter your comment!
Please enter your name here