Ping Viewer - Custom Gradients

Hello,

I’ve been making some custom gradients for Ping Viewer that are perceptually uniform to be able to more clearly differentiate different data levels (as per colorcet). That’s been working really well, and I’ve written some short python code to make valid gradient files from a given colorcet colourmap, e.g.

import colorcet as cc
with open('Rainbow.txt', 'w') as gradient:
    # colorcet uses 256-value colourmaps, Ping Viewer reads only the first 50 in a file
    colours = [colour for index, colour in enumerate(cc.rainbow) if index % 5 == 0]
    gradient.write('\n'.join(colours))

which gives a result like this (in air, so no objects to see)

I thought it could be useful/interesting to make the lowest level transparent, since in the custom gradients documentation for Ping Viewer it says that it’s possible to use #AARRGGBB as a colour-specification option, which I’m assuming means AA is the alpha/transparency channel. I’ve made a file with all the rows matching that form, but it doesn’t come up as an option in Ping Viewer.

All the other custom options work fine (e.g. 3,6,9,12 values), so it seems like something is wrong with the 8-value recognition, which sadly is the only one that supposedly allows for transparency.

If it matters, I’m on a MacBook Pro running PingViewer v2.1.0

1 Like

Hi @EliotBR,

Thank you for pointing this, I can confirm that the transparency feature is having some problems, we’ll investigate it more.
You can check the issue status here:

2 Likes

A comparison of ‘Rainbow’ (perceptually uniform - lightness uniform throughout range) with a few different perceptually linear (lightness increases linearly throughout range) options, for anyone who’s interested:

ping360-custom-colours-swatch

The perceptually linear options use both colour and lightness to differentiate values, with the lightness drawing more attention to higher intensities. The perceptually uniform (rainbow) option uses colour to differentiate values, and the warmer red/yellow colours draw more attention to higher intensities.

Adding the Ping Viewer defaults options thermal blue and monochrome sepia, black, and white to the bottom:

ping360-custom-colours-swatch-extra

  • Thermal blue has a bright yellow portion in the middle which focuses attention on mid-strength values, so relies on colour warmth to emphasise higher intensities.
  • The monochrome options use only lightness for both differentiation and emphasis.
  • Sepia has a more limited fidelity than the others because it has a lower total contrast.
  • Humans see small lightness changes more easily in dark regions than in light ones, so monochrome white would be most suited to identification/categorisation of an object material/shape/texture rather than finding objects.
  • Rainbow has uniform lightness, so is likely also well-suited to identification/categorisation

I should probably clean this up a bit and add the info to our docs.

I’d be interested to know if this is useful to you, and any questions it might raise :slight_smile:

Files

BGYW.txt (415 Bytes)
BMY.txt (415 Bytes)
Fire.txt (415 Bytes)
Rainbow.txt (399 Bytes)

4 Likes

Hi @EliotBR!

Thanks for sharing these gradients!
Just to update this post, the issue related to gradients with transparency information was solved, the one that I said in my previous post.

If someone wants to try, it’s available in our Daily Build.

I’m excited to see what the community will create and the beautiful patterns that we may see!
I’m also thinking to add a special place in Ping-Viewer documentation for some cool gradients that may be useful :blue_heart:

2 Likes

I was originally interested in transparency because I thought it could be helpful for making it extra clear where there’s ‘some signal’ vs ‘no signal’. That does seem to be the case, although how useful that is would depend on which sensor is being used, and what it’s being used for :slight_smile:


Files

BGYW_(T).txt (417 Bytes)
BMY_(T).txt (417 Bytes)
Fire_(T).txt (417 Bytes)
Rainbow_(T).txt (401 Bytes)

1 Like

@EliotBR

As promised, Here is my quick demonstration video of the Ping360 gradients. I wish that I was a little more scientific and went through a pre-planned route around the dock with each one, but I think the video I made is good enough for a start.

Rainbow is my favorite out of all of them since I think it is the most efficient at communicating the data to me. The Thermals are a very close second. I felt like the BMY and Fire gave the the ROV experience a interesting character since the purples and reds aren’t usually what I think of when I think about sonar displays.

0:00 BGYW
2:22 BMY
3:18 Fire
5:06 Rainbow
5:32 Sector Scan: Rainbow
5:44 Sector Scan: BGYW
5:56 Sector Scan: BMY
6:16 Sector Scan: Fire
6:34 Sector Scan: Rainbow
6:48 Sector Scan: Fire
6:53 Fire
9:19 BGYW
11:56 BMY
13:18 Sector Scan: BMY
14:30 Rainbow
16:43 Sector Scan: Rainbow
17:31 Rainbow
19:32 Thermal Blue
19:43 Monochrome Black
20:23 Monochrome White
21:21 Monochrome Sepia
22:27 Thermal Blue
23:27 Thermal Black
24:24 Thermal White
25:16 Thermal Blue

1 Like

Sweeeet, thanks for doing this and posting it :smiley:

Would probably be most useful to have a single route and just change the display on replays of the data. Unfortunately scan replays don’t support telemetry at the moment (I just raised an issue about it), so at this stage that would only be possible if the route is entirely in one direction. For correct alignment with the video that direction would be most convenient if it was north, although it’s at least possible to do some post-processing to create a duplicate .bin but with a constant angle offset to correctly display a non-north route. I suppose that’s technically also possible for a rotating route, although I imagine that would be more of a pain to do effectively, and I’m not sure how Ping Viewer would handle the result.

Fair enough - I think in this case the hues are useful because they effectively provide banding, which makes it easy to really quickly see it and think “this strong”, which is a bit harder to do with just lightness changes :slight_smile:
I think highest fidelity approach may be increasing lightness together with a logically rotating hue, with as many hue changes as possible without repeat (so possibly adding in some purple at the bottom or top end). That at least narrows down the space of options that are worth trying out.

Agreed - I feel like they looked cool but aren’t quite as easy to interpret, especially while in motion. I also think they look a bit aggressive when in a window with a blue background and next to a video with reasonably muted colours. That may be able to be resolved somewhat with adjusted/processed video, and possibly changing/removing the background of the Ping Viewer window. Very interesting stuff.

1 Like

It’s been a while, but I’ve just come across Dave Green’s “cubehelix, which is an exploration and implementation along the lines of what I was suggesting here:

I’m not sure if it’s actually better than rainbow, and it’s very possible there are better parameter combinations than what I’ve tried so far, but here are a couple of initial results for comparison purposes:

cubehelix

cubehelix_S=1-7_R=1-2_H=1-5_D=0_L=1.txt|attachment (399 Bytes)
cubehelix_S=1-7_R=2_H=1-3_D=0_L=0-95.txt|attachment (399 Bytes)

I generated them using the seaborn library’s cubehelix_palette function, e.g.

import seaborn as sns

S = 1.7 # starting hue (0-3)
R = 1.2 # number of full hue cycles
H = 1.5 # hue strength
D = 0   # dark level
L = 1   # light level

# Ping Viewer only accepts up to 50 colours for custom gradients
# 'reverse' to get a dark -> light gradient
cmap = sns.cubehelix_palette(50, start=S, rot=R, hue=H, dark=D, light=L, reverse=True)

filename = f'Cubehelix_{S=}_{R=}_{H=}_{D=}_{L=}'.replace('.', '-')+'.txt'
with open(filename, 'w') as gradient:
    # convert to hex colour strings, like #rrggbb
    colours = ['#'+(''.join(f'{round(c*255):02x}' for c in col)) for col in cmap]
    gradient.write('\n'.join(colours))
1 Like