How to use a 3d scatter with ML for Dash with callback

hi

I whant to use this scatter 3d with ml, in my dashboard, and need to have a callback,. how should the call back be?, and how do I arrange the data so it fits (X and y) to what I have (nan and differente shapes)?(what changes and where)

this is the 3d chart with ml Im going to use:

import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from sklearn.svm import SVR

mesh_size = .02
margin = 0

df = px.data.iris()

X = df[['sepal_width', 'sepal_length']]
y = df['petal_width']

# Condition the model on sepal width and length, predict the petal width
model = SVR(C=1.)
model.fit(X, y)

# Create a mesh grid on which we will run our model
x_min, x_max = X.sepal_width.min() - margin, X.sepal_width.max() + margin
y_min, y_max = X.sepal_length.min() - margin, X.sepal_length.max() + margin
xrange = np.arange(x_min, x_max, mesh_size)
yrange = np.arange(y_min, y_max, mesh_size)
xx, yy = np.meshgrid(xrange, yrange)

# Run model
pred = model.predict(np.c_[xx.ravel(), yy.ravel()])
pred = pred.reshape(xx.shape)

# Generate the plot
fig = px.scatter_3d(df, x='sepal_width', y='sepal_length', z='petal_width')
fig.update_traces(marker=dict(size=5))
fig.add_traces(go.Surface(x=xrange, y=yrange, z=pred, name='pred_surface'))
fig.show()

hi @topotaman
Could you please clarify your goal. You wrote that you would like to connect the scatter 3d with ML. How exactly would you like them connected. What is the Machine learning part that you would like to connect to the scatter 3d?

yes … I whant to do the scatter that I put up, getting data from a csv, using columns as dropdown, and doing the scatter 3d with the latice.

The ml is written above *model svr

the part I had more problems, is the data, if I used my data, it had nan, and also, I didnt reach there, but there might be problems of shape, so I should reshape and drop nan.

You can do something like this to allow users to choose the columns from the dropdown:

import dash
from dash import Input, Output, dcc, html, ctx
import plotly.express as px

df = px.data.iris()

app = dash.Dash(__name__)
app.layout = html.Div(
    [
        cols := dcc.Dropdown([col for col in df.columns], multi=True),
        my_graph := dcc.Graph()
    ]
)

@app.callback(
    Output(my_graph, "figure"),
    Input(cols, "value"),
    prevent_initial_call=True
)
def udpate_graph(col_list):
    dff = df[col_list]
    # ML stuff going on in this section
    # ...
    # build your 3d scatter figure
    # return figure
    return {} 


if __name__ == "__main__":
    app.run_server(debug=True)

hi … I dont see a graph (only something broken

can you see what is wrong?


import dash
from dash import Input, Output, dcc, html, ctx
import plotly.express as px
from csv import reader
import pandas as pd
import numpy as np
from pandas import DataFrame
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from sklearn.svm import SVR

df = pd.read_csv("data.csv")
tmp = df.select_dtypes(include=['Int64'])
df[tmp.columns]= tmp.astype('float64')

#df=df[1:].astype(dtype=np.float32, copy=True, errors='raise')
file_name = "data.csv"

with open(file_name, "r", encoding='cp437') as csv_file:
    csv_reader = reader(csv_file)
    head = next(csv_reader)
    print("head:")
    print(", ".join(head))
    #print("Values:")

    for row in csv_reader:
        (", ".join(row))


app = dash.Dash(__name__)
app.layout = html.Div(
    [
        cols := dcc.Dropdown([col for col in df.columns], multi=True),
        my_graph := dcc.Graph()
    ]
)

@app.callback(
    Output(my_graph, "figure"),
    Input(cols, "value"),
    prevent_initial_call=True
)
def udpate_graph(col_list):
    mesh_size = .02
    margin = 0
    dff = df[col_list]
    X = dff[['A, 'B']]
    y = dff['C']

    # Condition the model on sepal width and length, predict the petal width
    model = SVR(C=1.)
    model.fit(X, y)

    # Create a mesh grid on which we will run our model
    x_min, x_max = X.min() - margin, X.max() + margin
    y_min, y_max = X.min() - margin, X.max() + margin
    xrange = np.arange(x_min, x_max, mesh_size)
    yrange = np.arange(y_min, y_max, mesh_size)
    xx, yy = np.meshgrid(xrange, yrange)

    # Run model
    pred = model.predict(np.c_[xx.ravel(), yy.ravel()])
    pred = pred.reshape(xx.shape)

    # Generate the plot
    fig=my_graph
    fig = px.scatter_3d(df, x='A', y='B', z='C')
    fig.update_traces(marker=dict(size=5))
    fig.add_traces(go.Surface(x=xrange, y=yrange, z=pred, name='pred_surface'))
    fig.show()
    return fig


if __name__ == "__main__":
    app.run_server(debug=True)

hi @topotaman

I can’t run your code on my computer because I don’t have your data file.

But from what I see, you are missing a closing quotation mark around the A.

X = dff[['A, 'B']]
Should be:
X = dff[['A', 'B']]

What error message are you getting?

hi, thats not the problem …
the problem is this:

the graph is shown like this … no error appears. but graph doesnt show correctly.

the data is a only a list of numbers with headers …

is there a way for you to share the data.csv sheet with us; maybe through google sheets in google drive? Or maybe create a similar minimal reproducible example so we can run this locally?

adam … its just a spread sheet … with numbers … in float … 2 decimals … and some NaN … and all by columns with headers … and I use the headers to choose columns … that cant be the problem

I cant share de data coz its private

Just provide us a sample file with dummy data. No need to share anything private, but it helps a lot if we don’t have to guess what data you could be using and spend an hour trying to reproduce it.

Y A B C D E F G H I J K L M N O P Q R S T U W X
LemonDanilemon -300 1 0 0 NaN 100 0 0 NaN NaN NaN NaN 100 NaN NaN NaN -343.75 -343.75 NaN NaN NaN NaN NaN
Gom√£o96 320 1 100 100 NaN 100 99 99 NaN NaN NaN NaN 100 100 NaN NaN -258.95 -258.95 NaN NaN NaN NaN NaN
csecret -300 4 0 0 NaN 33.33 0 0 NaN NaN NaN NaN 50 25 NaN NaN -220.05 -220.05 NaN NaN NaN NaN NaN
tooon51 -300 3 33.33 0 NaN 66.67 33 0 NaN NaN NaN NaN 100 100 NaN NaN -218.17 -218.17 NaN NaN NaN NaN NaN
Mambomen123 320 3 100 100 NaN 100 99 99 NaN NaN NaN NaN 50 0 NaN NaN -182.13 -182.13 NaN NaN NaN NaN NaN
morfeo8384 -200 6 33.33 100 NaN 33.33 33 99 NaN NaN NaN NaN 66.67 0 0 NaN -150 -150 NaN 99 0 NaN 99
monteirinha -110 4 0 NaN NaN 0 0 NaN NaN NaN NaN NaN 50 0 NaN NaN -137.5 -137.5 NaN NaN NaN NaN NaN
prince77671 -160 5 0 0 NaN 25 0 0 NaN NaN NaN NaN 80 25 99 99 -124.12 -124.12 NaN NaN 99 99 NaN
Inokas74 -40 2 0 NaN NaN 0 0 NaN NaN NaN NaN NaN 50 0 NaN NaN -100 -100 NaN NaN NaN NaN NaN
juanpelm83 -20 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN -100 -100 NaN NaN NaN NaN NaN
fathyjrana -40 2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 50 0 NaN NaN -100 -100 NaN NaN NaN NaN NaN
Mjm2022 -60 7 25 100 NaN 25 25 99 NaN NaN NaN NaN 85.71 50 NaN NaN -79.75 -79.75 NaN NaN NaN NaN NaN
Dragoman25 350 4 66.67 100 NaN 66.67 67 99 NaN NaN NaN NaN 75 75 NaN NaN -76.36 -76.36 NaN NaN NaN NaN NaN
caradebolita -40 3 0 NaN NaN 0 0 NaN NaN NaN NaN NaN 100 33.33 NaN NaN -66.67 -66.67 NaN NaN NaN NaN NaN
tololondria -350 12 0 0 NaN 33.33 0 0 NaN NaN NaN NaN 27.27 0 NaN NaN -65.1 -65.1 NaN NaN NaN NaN NaN
TonyheadsupA -80 5 0 NaN NaN 0 0 NaN NaN NaN NaN NaN 60 20 NaN NaN -60 -60 NaN NaN NaN NaN NaN
djakini 50 20 40 50 NaN 80 40 50 NaN NaN NaN NaN 31.58 33.33 NaN NaN -57.82 -57.82 NaN NaN NaN NaN NaN
vidivixi 20 13 50 50 NaN 100 50 50 NaN NaN NaN NaN 27.27 33.33 0 NaN -56.5 -56.5 NaN NaN 0 NaN NaN
BerelR -10 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN -50 -50 NaN NaN NaN NaN NaN
brunolimex -10 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 0 NaN NaN -50 -50 NaN NaN NaN NaN NaN
DearLilith -210 6 33.33 0 NaN 66.67 33 0 NaN NaN NaN NaN 33.33 0 0 NaN -47.68 -47.68 NaN NaN 0 NaN NaN
Shaka169 -485 24 20 50 NaN 40 20 50 NaN NaN NaN NaN 26.09 0 0 NaN -47.17 -47.17 NaN 99 0 NaN NaN
Lokasalpoder66 -300 4 33.33 33.33 NaN 100 33 33 NaN NaN NaN NaN 100 100 NaN NaN -46.07 -46.07 NaN NaN NaN NaN NaN
zoser_tbm -300 10 33.33 25 NaN 66.67 33 25 NaN NaN NaN NaN 55.56 11.11 0 NaN -45.18 -45.18 NaN 99 0 NaN NaN
mjcuervos -90 7 33.33 NaN NaN 0 33 NaN NaN NaN NaN NaN 50 0 0 NaN -42.86 -42.86 NaN 99 0 NaN NaN
Lauzinhasilva09 -105 9 33.33 NaN NaN 0 33 NaN NaN NaN NaN NaN 25 0 NaN NaN -38.89 -38.89 99 NaN NaN NaN NaN
jbolinhas -95 13 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 30 0 NaN NaN -34.62 -34.62 NaN NaN NaN NaN NaN
zesardinha88 -25 3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 0 NaN NaN -33.33 -33.33 NaN NaN NaN NaN NaN
VSP1964 200 21 60 100 NaN 40 60 99 NaN NaN NaN NaN 35 15.79 NaN NaN -26.23 -26.23 NaN NaN NaN NaN NaN
Pablonoia10 -15 8 0 NaN NaN 0 0 NaN NaN NaN NaN NaN 50 16.67 NaN NaN -25 -25 NaN NaN NaN NaN NaN
filtrin1990 -45 6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 16.67 25 NaN NaN -25 -25 NaN NaN NaN NaN NaN
djbarrones -25 9 40 100 NaN 20 40 99 NaN NaN NaN NaN 33.33 0 50 NaN -22.22 -22.22 NaN NaN 50 NaN NaN
marmentia 15 7 66.67 NaN NaN 0 67 NaN NaN NaN NaN NaN 40 20 99 NaN -14.29 -14.29 NaN NaN 99 NaN NaN
rferreira1s 105 8 100 100 NaN 33.33 99 99 NaN NaN NaN NaN 62.5 28.57 NaN NaN -10.3 -10.3 NaN NaN NaN NaN NaN
soultaste -15 8 25 0 NaN 25 25 0 NaN NaN NaN NaN 71.43 33.33 0 NaN 0 0 NaN 99 0 NaN NaN
chanita07015 -5 6 50 NaN NaN 0 50 NaN NaN NaN NaN NaN 33.33 20 NaN NaN 0 0 NaN NaN NaN NaN NaN
iban06 0 3 100 NaN NaN 0 99 NaN NaN NaN NaN NaN 33.33 0 NaN NaN 0 0 NaN NaN NaN NaN NaN
IRISCIBLE 0 3 0 NaN NaN 0 0 NaN NaN NaN NaN NaN 33.33 33.33 NaN NaN 0 0 NaN NaN NaN NaN NaN
miguel0034 -240 18 33.33 0 NaN 66.67 33 0 NaN NaN NaN NaN 60 58.33 NaN NaN 1.88 1.88 NaN NaN NaN NaN NaN
festuket 55 16 50 66.67 NaN 75 50 67 NaN NaN NaN NaN 40 36.36 NaN NaN 7.71 7.71 NaN NaN NaN NaN NaN
dacaro78 15 7 50 NaN NaN 0 50 NaN NaN NaN NaN NaN 33.33 0 50 NaN 14.29 14.29 NaN 99 50 NaN NaN
Jorlogar -35 16 100 100 NaN 50 99 99 NaN NaN NaN NaN 35.71 27.27 NaN NaN 16.01 16.01 NaN NaN NaN NaN NaN
gesto sport 15 5 100 NaN NaN 0 99 NaN NaN NaN NaN NaN 25 0 NaN NaN 20 20 NaN NaN NaN NaN
catiafabio 20 4 33.33 NaN NaN 0 33 NaN NaN NaN NaN NaN 75 25 NaN NaN 25 25 99 NaN NaN NaN NaN
christiiann_16 420 6 75 50 NaN 50 75 50 NaN 0 NaN NaN 100 20 99 NaN 30.36 30.36 NaN NaN 99 NaN NaN
Georgi0202 30 4 66.67 NaN NaN 0 67 NaN NaN NaN NaN NaN 75 0 99 NaN 37.5 37.5 NaN NaN 99 NaN NaN
Esmifrado 80 9 100 NaN NaN 0 99 NaN NaN NaN NaN NaN 28.57 14.29 NaN NaN 38.89 38.89 NaN NaN NaN NaN NaN
Chf-Rdr 295 18 66.67 100 NaN 33.33 67 99 NaN NaN NaN NaN 50 53.85 0 NaN 44.44 44.44 NaN NaN 0 NaN NaN
pakito199388 147 6 100 100 NaN 33.33 99 99 NaN NaN NaN NaN 60 25 NaN NaN 46.65 46.65 NaN NaN NaN NaN NaN
jordireus 10 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 50 50 NaN NaN NaN NaN NaN
kakan62 430 4 66.67 100 NaN 33.33 67 99 NaN NaN NaN NaN 100 33.33 NaN NaN 73.07 73.07 NaN NaN NaN NaN NaN
yajisss 365 8 100 100 NaN 100 99 99 NaN NaN NaN NaN 62.5 57.14 NaN NaN 74.35 74.35 NaN NaN NaN NaN NaN
0`Darius 525 16 66.67 100 NaN 50 67 99 NaN NaN NaN NaN 62.5 38.46 0 NaN 76.41 76.41 NaN 99 0 NaN NaN
davidga777 270 9 100 100 NaN 100 99 99 NaN NaN NaN NaN 22.22 20 NaN NaN 89.38 89.38 NaN NaN NaN NaN NaN
guerreiro1969 380 5 100 100 NaN 33.33 99 99 NaN NaN NaN NaN 80 20 NaN NaN 111.3 111.3 NaN NaN NaN NaN NaN
Mazanita222 326 21 83.33 75 NaN 66.67 83 75 NaN NaN NaN NaN 52.94 25 33 NaN 111.72 111.72 NaN NaN 33 NaN NaN
0miickey0 290 4 100 100 NaN 100 99 99 NaN NaN NaN NaN 25 25 NaN NaN 113.11 113.11 NaN NaN NaN NaN NaN
kuxku39 -300 4 33.33 0 NaN 66.67 33 0 NaN NaN NaN NaN 66.67 0 NaN NaN 126.36 126.36 NaN NaN NaN NaN NaN
jorgens35 410 4 100 100 NaN 33.33 99 99 NaN NaN NaN NaN 75 25 NaN NaN 150.56 150.56 NaN NaN NaN NaN NaN
gonzalorolda 390 4 66.67 100 NaN 66.67 67 99 NaN NaN NaN NaN 75 66.67 NaN NaN 158.57 158.57 NaN NaN NaN NaN NaN
Loma93 315 3 100 100 NaN 33.33 99 99 NaN NaN NaN NaN 100 100 NaN NaN 296.72 296.72 NaN NaN NaN NaN NaN
MrFlooopy 180 3 100 NaN NaN 0 99 NaN NaN NaN NaN NaN 66.67 33.33 NaN NaN 300 300 0 NaN NaN NaN NaN
mestreamorim 320 2 100 100 NaN 50 99 99 NaN NaN NaN NaN 50 50 NaN NaN 330.92 330.92 NaN NaN NaN NaN NaN

heres data. done

import dash
from dash import Input, Output, dcc, html, ctx
import plotly.express as px
from csv import reader
import pandas as pd
import numpy as np
from pandas import DataFrame
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from sklearn.svm import SVR

df = pd.read_csv("data.csv")
tmp = df.select_dtypes(include=['Int64'])
df[tmp.columns]= tmp.astype('float64')

#df=df[1:].astype(dtype=np.float32, copy=True, errors='raise')
file_name = "data.csv"

with open(file_name, "r", encoding='cp437') as csv_file:
    csv_reader = reader(csv_file)
    head = next(csv_reader)
    print("head:")
    print(", ".join(head))
    #print("Values:")

    for row in csv_reader:
        (", ".join(row))


app = dash.Dash(__name__)
app.layout = html.Div(
    [
        cols := dcc.Dropdown([col for col in df.columns], multi=True),
        my_graph := dcc.Graph()
    ]
)

@app.callback(
    Output(my_graph, "figure"),
    Input(cols, "value"),
    prevent_initial_call=True
)
def udpate_graph(col_list):
    mesh_size = .02
    margin = 0
    dff = df[col_list]
    X = dff[['A, 'B']]
    y = dff['C']

    # Condition the model on sepal width and length, predict the petal width
    model = SVR(C=1.)
    model.fit(X, y)

    # Create a mesh grid on which we will run our model
    x_min, x_max = X.min() - margin, X.max() + margin
    y_min, y_max = X.min() - margin, X.max() + margin
    xrange = np.arange(x_min, x_max, mesh_size)
    yrange = np.arange(y_min, y_max, mesh_size)
    xx, yy = np.meshgrid(xrange, yrange)

    # Run model
    pred = model.predict(np.c_[xx.ravel(), yy.ravel()])
    pred = pred.reshape(xx.shape)

    # Generate the plot
    fig=my_graph
    fig = px.scatter_3d(df, x='A', y='B', z='C')
    fig.update_traces(marker=dict(size=5))
    fig.add_traces(go.Surface(x=xrange, y=yrange, z=pred, name='pred_surface'))
    fig.show()
    return fig


if __name__ == "__main__":
    app.run_server(debug=True)

Some notes on your code:

    X = dff[['A, 'B']]

should be

    X = dff[['A', 'B']]
fig=my_graph

is probably not needed (haven’t tested it)

fig = px.scatter_3d(df, x='A', y='B', z='C')

uses df from outside of the callback (global variable). Are you sure that’s the DataFrame you want to use?

fig.show()

is not needed anymore

It doesnt work, gives some errors.

I’m traying with this:

import dash
from dash import Input, Output, dcc, html, ctx
import plotly.express as px
from csv import reader
import pandas as pd
import numpy as np
from pandas import DataFrame
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from sklearn.svm import SVR

df = pd.read_csv("pokerdata.csv")
tmp = df.select_dtypes(include=['Int64'])
df[tmp.columns]= tmp.astype('float64')

#df=df[1:].astype(dtype=np.float32, copy=True, errors='raise')
file_name = "pokerdata.csv"

with open(file_name, "r", encoding='cp437') as csv_file:
    csv_reader = reader(csv_file)
    head = next(csv_reader)
    print("head:")
    print(", ".join(head))
    #print("Values:")

    for row in csv_reader:
        (", ".join(row))


app = dash.Dash(__name__)

df=df.copy()
chart9 = px.scatter_3d(data_frame=df,
                   x='VPIP',
                   y='PFR',
                   z='3Bet PF',
                   #color='!!!0 All-In Equity Adjusted BB/100',
                   #trendline="ols",
                   #trendline_color_override="red",
                   height=800,
                   width=800
                   )


graph9 = dcc.Graph(
        id='graph9',
        figure=chart9,
        #className="five columns"
    )
dropdown1_scatter3d_chart = dcc.Dropdown(
        id="dropdown1_scatter3d_chart",
        options=[{"value":label, "label":label} for label in df.columns],
        value=df.columns[0],
        clearable=False
    )
dropdown2_scatter3d_chart = dcc.Dropdown(
        id="dropdown2_scatter3d_chart",
        options=[{"value":label, "label":label} for label in df.columns],
        value=df.columns[0],
        clearable = False
    )
dropdown3_scatter3d_chart = dcc.Dropdown(
        id="dropdown3_scatter3d_chart",
        options=[{"value":label, "label":label} for label in df.columns],
        value=df.columns[0],
        clearable = False
    )

scatter3_div = html.Div(children=[html.Div(children=[dropdown3_scatter3d_chart, dropdown1_scatter3d_chart,dropdown2_scatter3d_chart], className="row") , graph9], className="eight columns")

row6 = html.Div(children=[scatter3_div], className="eight columns")

layout = html.Div(children=[row6], style={"text-align": "center", "justifyContent":"center"})

app.layout = layout

@app.callback(
    Output(graph9, "figure"),
    Input(dropdown1_scatter3d_chart, "value"),Input(dropdown2_scatter3d_chart, "value"),Input(dropdown3_scatter3d_chart, "value")
    
)
def udpate_graph(drop1,drop2,drop3):
    mesh_size = .02
    margin = 0
    dff = df[drop1]
    X = dff[['VPIP', 'PFR']]
    y = dff['3Bet PF']

    # Condition the model on sepal width and length, predict the petal width
    model = SVR(C=1.)
    model.fit(X, y)

    # Create a mesh grid on which we will run our model
    x_min, x_max = X.min() - margin, X.max() + margin
    y_min, y_max = X.min() - margin, X.max() + margin
    xrange = np.arange(x_min, x_max, mesh_size)
    yrange = np.arange(y_min, y_max, mesh_size)
    xx, yy = np.meshgrid(xrange, yrange)

    # Run model
    pred = model.predict(np.c_[xx.ravel(), yy.ravel()])
    pred = pred.reshape(xx.shape)

    # Generate the plot
    fig=graph9
    fig = px.scatter_3d(dff, x=drop1, y=drop2, z=drop3)
    fig.update_traces(marker=dict(size=5))
    fig.add_traces(go.Surface(x=xrange, y=yrange, z=pred, name='pred_surface'))
    #fig.show()
    return fig


if __name__ == "__main__":
    app.run_server(debug=True)

but there is an error with the ml

KeyError: "None of [Index(['VPIP', 'PFR'], dtype='object')] are in the [index]"

how can I solve this?

My problem is this … the ml … uses what? 2 columns of data for X? or what? how do I have to reshape it so it works?

 X = dff[['A, 'B']]

First, you set dff to a subset of columns from your Dropdown 1. Then you set X to a subset of the previous subset of columns. So if your Dropdown 1 does not contain the columns VPIP and PFR, it will end in a KeyError.

I mean your code more or less looks like the example here (Ml regression in Python) so I guess your problem mainly has to do with how you handle the data. Try it with the Iris dataset, print out X. Then make sure that when you print out X with your dataset, it has the same shape as the Iris dataset.

hi, I get this error

"

None of [Float64Index([38.64,  50.0, 56.25, 23.08, 41.67, 41.89,  50.0, 52.38, 38.89,\n              60.87,\n              ...\n              55.56,  48.0, 35.71, 35.48, 47.83, 18.75, 26.32, 28.57, 14.29,\n              38.89],\n             dtype='float64', length=545)] are in the [columns]"``


ow can I solve this?

I´ve tried indexing with this:

dataXX=pd.DataFrame(dff[drop1])
    dataXX=dataXX.loc[:,dff[drop2]]
    dataXXX = dataXX.set_index(dff[drop1],dff[drop1])

I dont know how its printing … because it doesnt reach there …

I have to finish this work … I could pay