pygraphistry
pygraphistry copied to clipboard
[FEA] luminosity encoding
Is your feature request related to a problem? Please describe.
In some scenarios, an extra dimension can help, and luminosity is one of them. Additional, a secondary key for normalization can also help.
Describe the solution you'd like
Something like:
import math, numpy as np
def with_coloring(base_g, point_colors: dict, point_color_default: int):
"""
sets base color by base_g._nodes.type and then luminosity by inferred degree
"""
#log-scale 'g2._nodes.degree'
g2 = base_g.nodes(base_g._nodes[[base_g._node, 'type']].reset_index(drop=True)).get_degrees()
g2 = g2.nodes(g2._nodes.assign(degree=pd.Series(np.log(g2._nodes['degree'].values))))
degs = g2._nodes.degree
colors = g2._nodes['type'].map(point_colors).fillna(point_color_default).astype('int64')
# color multiplier: color_final = color_base * (min_luminosity + (1 - min_luminosity) * multiplier)
min_luminosity = 0.5
type_to_min_degree = g2._nodes.groupby('type').agg({'degree': 'min'}).to_dict()['degree']
type_to_max_degree = g2._nodes.groupby('type').agg({'degree': 'max'}).to_dict()['degree']
mns = g2._nodes['type'].map(type_to_min_degree)
mxs = g2._nodes['type'].map(type_to_max_degree)
multiplier = (degs - mns + 1.0) / (mxs - mns + 1.0)
multiplier = min_luminosity + (1 - min_luminosity) * multiplier
rgbs_arr = [
pd.Series(c & 255, dtype='int')
for c in [colors.values >> 16, colors.values >> 8, colors.values]
]
weighted_arr = [
pd.Series(np.floor((c * multiplier).values)).round().astype('int64').values
for c in rgbs_arr
]
rgb = (weighted_arr[0]<<24) | (weighted_arr[1]<<16) | (weighted_arr[2]<<8)
colors = pd.Series(rgb, dtype='int64')
return (base_g
.nodes(base_g._nodes.reset_index().assign(pc=colors))
.bind(point_color='pc'))
Describe alternatives you've considered
Via just pygraphistry
- note how this works off of a known computed per-entity color; would be better if not
- with and without log scaling
- luminosity can really be by mixing in black, white, or some other color
- with and without secondary dimension ("degree" vs "degree partitioned by type")
- default on degree
Via backend:
- enables legend support & multi-client
- server likely would reuse this impl, so a good start