Fluid.datasetplot~ abstraction for 2D/3D visualization

Here you go.

I added a couple more colorspaces (greyscale and colorblind) too.

fluid.datasetplot~2.zip (384.9 KB)

This has already come in useful!

2 Likes

I don’t know about you, but I see a pterodactyl fighting a velociraptor.

2 Likes

Probably a better way to do this, but here’s another update.

I remembered speaking to @tedmoore a while back about checking to see how two spaces map onto each other but applying the same fit before plotting it. The previous version of this automatically normalizes your incoming dataset so it would be impossible to visualize something that only uses a portion of the available range.

So with that there’s now a @normalize attribute that will either automatically normalize the incoming fluid.dataset~ (default behavior) or will pass the dataset along untouched. This can obviously exceed the bounds of the display, so you’re on your own there.

If there’s a way to clamp a dataset to a range (without scaling it) that may be a handy alternative here too, but for now it will display things “off the chart”.

fluid.datasetplot~.zip (389.0 KB)

Ooh. Yes, I like the idea of having a “normalize” flag, but yes, my thinking was that the plotter expects everything in a range 0-1. That way the user can decide how they want it scaled (for example frequencies scaled down exponentially from 20-20k or just normalize frequencies to whatever range they have as two very different options). That way those decisions are made outside the scope of the plotter, which is just intended to do plotting.

Totally.

In my version here you feed it an arbitrary dataset and it will then do the normalizing for you (for quick/dirty viewing), but that’s not always great as it will spread things out to 0-1 regardless of the input.

I could leave it so it expects 0 to 1 and you’re on your own to normalize too, but I wanted something that you could take a dataset, as it is, and visualize it without much faff.

edit:
It was specifically me thinking “Ooh, I should finally try that thing that @tedmoore suggested a while back” when I realized that I can’t actually do that with the abstraction as it was before.

1 Like

Here’s an update that changes the LUT for the hsl representation, as that’s what’s most useful for kmeans cluster viewing (as per this thread).

4 clusters from kmeans (linear display):

4 clusters (previous hsl):

4 clusters (new hsl):

fluid.datasetplot~.maxpat.zip (38.8 KB)

1 Like

I wish there was quanlification of the :heart: icon - this would get at least to 11

1 Like

obviously I’m adding a feature though :slight_smile: I love community coding.

You can see the ‘missing’ feature of a zoom. so far called range, to be able to decide the range of the presentation grid. I’ll medidate a bit further to decide if x and y should be different (more work) but so far they are the same and it works well - the coding I’m hacking is not as clean as @rodrigo.constanzo 's, as you can imagine :slight_smile:

1 Like

I’m fighting an ‘interesting unexpected feature’. Can you try this patch as is and tell me if you only get a red dot in the top left?

If yes and not unexpected, what am I missing in my patch to make a simple query work?

thanks

p


----------begin_max5_patcher----------
1096.3ocyXtsaaiCDF9Z6mBBg16bb4AqS4x80Xwh.JIZG1HKJPQ65rEsO6KO
H65jHGSqCFKBhEDIk94mlgCmg+b9rfLwAVS.3QveClM6mymMy1jogYs2OKXK
8PdIswNrfsrlF5FVvBWeJ1Aksc3wVp1sUrSUxT1wiZaslpxelWs4IIKW4zCQ
HKgK.woglKgPyuX7RH3eZeF2qQ8ZMy8.AAm5hWXEUj88GVQNSYd0Qgwl1907
4leVLP1vEaj7h+51IbUjApTzf.jDN4.VK4UpaGODDaXZEJ0bgf6KfimErh8C
8arC9X0rpBPofVzCLCSOCy3z9hIpSLQiHlz7W.MLEHWT1.v8fTxJCbHhcIYR
ReIE1IojwiTEHS+WdIiJ6lRxkoLEaoKNx4zFecHynUaBV7mqNc6hbb5TaiK3
4WXk5pq6BSRgsghBuFyFc3hJp7UCwm9uSnS5d8aaiMz8rhmzCTOcdhpTRd1N
kaSmYmXeV.aaFy9NgKZaolJoaYJl7IVEMqjcgN2RqqO0ssW6W5wMzwMuVJs8
KN1dIjzykR33o1gpwF7esMtgl0RZNCTPUzGerVn63gu1zW1QIQtK8F9noF98
rC0RvWVi.eCDt7lAMI1E8vsrJtuwKwqtG6Lza5hrz41ZnOzgm5s2e.Dd69nH
qyIF4vJ85QDMoH0Ien+Ox2Qi2HvGbp46q5Mn5KfsAYbYrzO.QwSMfeqO.15g
1B3PrfnnQCP8V2JQUOLV1hChrUBgWc72qjxUmrbZovmjdvjEGc2+xAHLB.u4
rNSHt8DQ1ODg8HqyKZcm73OqK2wKVZRJPmjvuAeZ4vexm.D1Uw+p1zCvg9+Q
XstzM0Ey.EAGsMPUhMaJY2rCNwU86JnuN3WxZldWbuuzAATIjaok7FF3K2d.
KBxU1nq7p3dltv3ELNyNGYmpPbOm8i87FdFujqd8bXDqWq8rcyJqEDd1ztTj
+BqnPR2zjKEkkmaHxK44undVJ1s44ya2Yxd9iOfqi8erirMaEEuwHmIjE5I+
aM69dvSs0wagIBhbWf9YLpz9cebcecoP86k5Ov0zSEfddVBW0rYe+Ak7p2ef
iV.Ls+VaYiXmL+3rq0y.7G.JXMJdE0Tj5YiA6FSmdK9pi4.2tKBg8PGywaBP
CTnTODJdL9xQ7PHSv5gqD5toDzGugjwvcH0Yp+TkHvwRIrmLcLfwwnQngK8U
Mbn6EjHX2PBGlzId.IYTfL9t4cF4iRiQTDywgbmTxmHvGmNCSIehWYmNCMVO
F5qRCkIjW9diQ7JjW9diw5IjW68mNFJg7HZ+6BjrkWXOT11DnRhhMGJ.IgXt
fPQImtcLlbWcChnoH1oWR+NWuSRiuCRGc8sEco5Rqq2yjMsOtUUcAJeWXGdx
B6s7J2s1j4CjLS8ItwirY8GPk5j6U5L62IcIkeHxcZwAl5EjU63shqAdtofD
c0OlD3apoN1rEIM+Wy+O.Rw+SKA
-----------end_max5_patcher-----------

ok I found the bug: the naming convention for the entries is numerical only. I’ll mod the patch to make it work with arbitrary entry label

1 Like

ok a few bugs found and sorted, this is still work in progress but I added the range of the display and the radius of the nearest neighbourg requested

stuff I’ll add next is probably a gate on click (querying just when click) as an option but for now further testing welcome

Archive.zip (42.6 KB)

1 Like

Good additions!

I did think about the int vs symbol thing but I viewed that aspect of it as just kind of a built in bonus, so didn’t bother changing it.

And the range is good as well. I changed the patcherargs section to this:

That way the range updates dynamically too (much easier than guessing what you want to scale it to and rebanging manually).

1 Like

what is your view on the clicking, and on the number of neighbours? The latter I could think of something like what @weefuzzy has implemented in the helpfile colouring but that is more hard work…

Clicking is a great idea actually. Or having a flag for @onclick or something, so if you just want to wiggle around (without clicking) you can do that too.

The radius thing is cool, though unless it starts spitting out more than a single match, it would always just match on itself, and therefore not matter for most cases? I could be missing what the purpose of that is.

I know what @radius is good for in a general sense, but here the (internal) dataset and display are coupled, so not sure what it’s for here.

the way I set it up now, it has @numneighbourg to 1 and with radius 0 will give you whatever is the nearest, whatever the distance. I find that mode much more intuitive but wanted to support yours too.

Ah right. Yeah that’s what I was aiming for, I just did it via @radius instead, as it was on my mind at the time. But the original idea there was for it to tell you what single point you’re hovering over.

A more useful, though larger, change would be to have more values being returned as a list, but that starts to become a bit more a standalone patch or example.

A change like being able to have symbolic labels would also make for a handy pre-processing abstraction where you can start with a larger dataset and then visualize up to 3 arbitrary dimension from it, ala @tedmoore’s plotter.

1 Like

It seems like it’s broken for non-symbol labels now. I’ve not traced through completely to see what you’ve changed, but I noticed my previous .maxhelp wasn’t working anymore (loads of Point not found error messages), then going back to the version you posted here to figure out that if you change the sprintf to have %ld it throws the same error. So something along the way doesn’t like having ints as labels.


----------begin_max5_patcher----------
1272.3ocyZssbihCD8Y6uBUTy7liGjDWyi6uwVakR.xNZBFnDxdb1ol4aeER
DGl3aJPGmsRESYIfiNp69zcqjeNelWV8ddqG5dzeilM6mymMyLT2.y5+9LuM
r84krVys4sg21xVy8VXmqdqpjqTO2vsuDOOz+zOUCSk+nnZ8CRdtxNKlPhV5
u.QCi6tD528Igrz+vCUscinR+FMfQdcPKNlQw8iJJLKn5rueG0qaneMed2GK
bjIqJq0u3ySjEHuLV05KRHJk1Qg.hKzAeR5PNlN3DuCPJYa3Jt7AdEKqzr17
6maUsbCyrNhFA6eicTw2adUdRVgXaK5K3wYgoTyVQhYqHLAH6KdTF3yQwlZQ
k5tnzwwvn3zNVEYL7gDfXXH.D7cFKZcciSCAMTL3SKVLDaEUvfFKFf+3iEq3
+PC0w9ormPRMq4H+kH7xwYlChL6JXeabY5k2VnNal8+rLyAA9e.lYZ7mmjKo
XsTT7WiLLNvjQMECaB0PPEbkZA2QRudG2.rwykBkdKcTxTmKPUxa3UEnxZVw
XoYX5.ZFmNF25SQSLjzjk+DpkqP40ksHxXYJMvHHQM4cRR.RPh5CHSUnL8O4
kbl7rrzHTs30q169RTOkXnbrsDXR7XrwziYNIEPlWHxOejZ2jh5Jl74NBe3W
Wbroo98BTgu+32fSP5CkH2x1wKdPOlFyGXJkTjsUY6oY1AtOyiuIiWLPK+hB
8CmbCqo4vzlYM6zvJcLtXoz98Vh4RHEHQCRLfNTsFw+UFcCMWKY4bTASwt+9
uVNMZiSLAR3vXn3cDf7dGeeiD8kUXz2Pgir1sjXK0rwNwIPwy.fSJLM1EYXm
Mq..Y1ID.Y2cnvyRttZZtnaJ13eRvVlkNFkuSwO7+S32K1On4GjIx+pNAzTI
XuNisdEHNLCHkW+1THXuGZOAAyBhGkNpNqspt5xkacYqko2fHSiPjfW9bhZk
3vK1WHbFxs+q.gIXjuyEbdU2WpMMI1d3jwiw88DkahgT+YU4VQwxt5Az0G7a
z05D9EpuR2ok550dR5Oc195EHg.UwMdTRTp50qK4iNXkDNTFBJ+6TncuO2Y.
T0czIkhV9nOZYh0e1dzxww.oFOJw3Lyxien4vcB9O1IZEYhRg54gHUuZk1y1
R.yB2evJtrN+IdQgjstMWVWVN7nlxKE4OodTVuc8iCG2Zcd73GvNwtimHa8l
5h+3XrxpkE5E+fQdum4TeK7FFE4isW7upwP6gcbXeSYs52K06uMrCsdd8pDF
Z1Ln5UJpd6eJKyZua7+zV1VuUl+BS60zzNSGV7E7Vknh00q6faR2df17c3ld
cO7jNPtB8adqmA5X6MMIjRc.HHvI1EBA.NgNhCdh3z8W.3p.E3a8flFR92ns
NZrqTZpadzvaEknN.D1GBjv2LjbxeHA.jHoVa8EQh5CERDG4zakZwSG5qZ3v
2JRh8+Pxmj3.IofPx3al2YvsJGIg3BRAPfjKpHDHxeQ7cEoIyIWxpPAfRXWb
xwT.nD1ImbHDFwNUHHDAtXmxImBARzaT1eipM98kUYinv7eBTeOCIQwcm+EM
g1cAiiRN7UHVbWMaP7oyFPtAPGc8rs1VrXMM63x19G2fptw3uWat8jEluJpr
e0zzlmj20Wr89wltM8XRc+jJcyjak1tA2GE3YeVcepxpshdv0DddWiv5tt65
brsgY4lo474+Z9+wNC.Ez
-----------end_max5_patcher-----------

Ok, it looks like it needs t b l everywhere, instead of t b s, as l passes on symbols, ints, floats, whatever, whereas s converts items.

2 Likes