-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Customize color scale and palette #399
Comments
I would love this! |
I’d like to recommend react-color as a nice picker component :) |
Hi, |
@heshan0131 Do we have actions/helpers to change layer's color programmatically? |
landed |
Hi, |
Hi, Cheers |
Is the value customization still in progress? |
This got put away for a little while, we just resumed the work. Should come out in the next month or so |
Hi, |
* color palette now has an Add value button to map ordinal values for selected color Signed-off-by: Marko Letic <marc.letic@gmail.com>
* color palette now has an Add value button to map ordinal values for selected color Signed-off-by: Marko Letic <marc.letic@gmail.com>
Hi heshan0131, sorry to bother you on this. Is the value customization still in the pipeline? |
Is the value customization ready to use? |
me too, I would love to use the value customization. |
Im waiting for this. it will be awesome... |
do we have any updates on this? |
I'm waiting for the opportunity to set the palette statically from min to max, and not relatively as now. |
do we have any updates on this? |
Really loved using Kepler so far!! Is there any updates on when value customization might be ready as it would be hugely helpful for my project? |
This feature is going to be available in studio.unfolded.ai and after beta testing it will be merged into our open source project |
Kepler is great!! Is there any updates on when value customization might be ready in Kepler.gl? |
Any chance this will be available in the open source project soon? Would be greatly appreciated ;) Thanks to the team for an awesome tool! |
Up vote for this function too! Thanks a lot! |
I'm reading the comments before not sure if I missed something or if the update still hasn't been published yet. Any updates on this update, please? |
Its almost 2023 and that feature still has not added :( |
|
Hi @heshan0131 @sinannoureddine @dancestorm @xiaofanliang @mletic |
Could be relevant for someone working with Kepler in Jupiter. I managed to work out how to bind colors to custom value ranges using colorMap & colorLegends properties: import pandas as pd
from keplergl import KeplerGl
from numpy import array
# Define color mapping routines ("less or equal" in this example)
class Mapper:
def __init__(self):
# Define custom palette & legend values
self.__ranges = {
2: { 'color':'#ff0000', 'legend':'<= 2' },
3: { 'color':'#00ff00', 'legend':'<= 3' },
4: { 'color':'#0000ff', 'legend':'> 3' }, # Key here must be >= than max value in dataset
}
self.__keys = array(list(self.__ranges.keys()))
# Estimate color based on a value
def __mapper(self, val:float) -> str:
return self.__ranges[self.__keys[self.__keys >= val].min()]['color']
# Prepare color map for Kepler config
def get_color_map(self, for_values: pd.Series) -> list:
return [[x,y] for x,y in zip(for_values, for_values.apply(self.__mapper))]
# Prepare color legends for Kepler
def get_color_legends(self) -> dict:
return { v['color']:v['legend'] for _,v in self.__ranges.items() }
# Prepare custom colors for Kepler
def get_colors(self) -> list:
return [v['color'] for _,v in self.__ranges.items()]
# Sample DataFrame
df = pd.DataFrame([[1,1,0],[2,2,0],[3,3,0],[4,4,0]], columns=['x','lon','lat'])
# Init Kepler
kgl = KeplerGl()
kgl.add_data(df)
kgl
# Pull out config
cfg = kgl.config
mapper = Mapper()
# Tweak it with the Mapper
color_range_for_layer = cfg['config']['visState']['layers'][0]['config']['visConfig']['colorRange']
color_range_for_layer['colors'] = mapper.get_colors()
color_range_for_layer['colorMap'] = mapper.get_color_map(df.x)
color_range_for_layer['colorLegends'] = mapper.get_color_legends()
# Re-Init Kepler and enjoy
kgl = KeplerGl(config=cfg)
kgl.add_data(df)
kgl It's a bit of a hack of course but works fine for me. Not tested on really big datasets :) |
Thanks |
Note - the above code from kungf00man only works for version 0.3.2.
and then also modify the call from above to --> |
Hi, |
@ahinoamp @kungf00man Thank you for sharing your findings. Here is code to get similar functionality (with automatic color scale according to 5% quantiles) for React: import { scaleLinear } from 'd3-scale';
import { color } from 'd3-color';
import { quantileSorted, ascending } from 'd3-array';
const Mapper = (vmin, vmax, n_steps) => {
// Define custom color scale using D3
const minColor = '#a6d96a';
const maxColor = '#a50026';
const colorScale = scaleLinear()
.domain([vmin, vmax])
.range([minColor, maxColor]);
const stepSize = (vmax - vmin) / (n_steps - 1);
const ranges = {};
for (let i = 0; i < n_steps; i++) {
const value = (vmin + stepSize * i).toFixed(2); // Rounded to 2 decimals
const hexColor = color(colorScale(value)).formatHex();
ranges[value] = {
color: hexColor,
legend: `<= ${value}`,
};
}
const keys = Object.keys(ranges);
// Estimate color based on a value
const mapper = (val) => {
const matchingKey = keys.find((key) => Number(key) >= val);
return ranges[matchingKey]?.color || maxColor; // Default to 'blue' if no match
};
// Prepare color map for Kepler config
const getColorMap = (forValues) => {
return forValues.map((val) => {
return [val, mapper(val)]
});
};
// Prepare color legends for Kepler
const getColorLegends = () => {
const legends = {};
Object.entries(ranges).forEach(([key, value]) => {
legends[value.color] = value.legend;
});
return legends;
};
// Prepare custom colors for Kepler
const getColors = () => {
return Object.values(ranges).map((range) => range.color);
};
return { getColorMap, getColorLegends, getColors };
};
function adjustColorRange(predictionData, predictionConfig, parameter) {
return (dispatch) => {
const visState = predictionConfig.config.visState;
if (visState.layers.length === 1) {
// Extract all parameter values from the features array
const featureValues = predictionData.features
.map(d => d.properties[parameter])
.filter(d => d !== null && !isNaN(d))
.sort(ascending)
const minValue = quantileSorted(featureValues, 0.05);
const maxValue = quantileSorted(featureValues, 0.95);
const mapper = Mapper(minValue, maxValue, 10);
visState.layers[0].config.visConfig.strokeColorRange = {
colors: mapper.getColors(),
colorMap: mapper.getColorMap(featureValues),
colorLegends: mapper.getColorLegends(),
};
}
};
} Call it as follows with your layer's data and config, before dispatching dispatch(adjustColorRange(predictionData, predictionConfig, 'no2')); |
Color Palette customization (done) #601
User should be able to design custom color palette, they should be able to
using custom color palette
to toggle color palette editorColor Value customization (in progress)
User should be able to import values next to each color, using dropdown for ordinal values and input box for numeric values. There will be a distribution graph for numeric values, user can drag the slider handle to adjust value range of each bin
Ordinal values
Implementation Step:
layer.config.colorUI.colorRange.customPalette
, create a new propcolorMap
and save it as a JS Maponly store values manually selected by user. if user is using the "assign rest to one color" option, don't store all the rest of the values to the map, later when create color scale, use the .
unknown()
method to assign color to the rest of values.layer.getVisChannelScale
(base-layer.js). Use D3.ordinalScale and pass in thecolorMap
and a value forunknown
[Numeric values]
Add more color scale options
Implementation steps:
1.5 add Jenkins natural breaks scale (in progress)
The text was updated successfully, but these errors were encountered: