I defined the color scheme of my barChart as follows :
var colorChoice = d3.scale.ordinal().domain(["negative","positive","test"])
.range(["#FF0000","#00FF00","#FFFF00"]);
myBarChart
.colors(colorChoice)
.colorAccessor(function(d) {
if (+d.data.value>0) {
console.log("positive");
return("positive");
} else {
console.log("negative");
return("negative");
}
});
But what happens when I renderAll() is that all bars are of the color of the first item of my colorChoice.domain() (so in that case #FF0000).
I tried switching the two first values in the domain and it is always the first one that is used.
I also verified that my colorAccessor function outputs values that should be correctly interpreted by `colorChoice. (cf console log below)
3 negative metrics:319
3 positive metrics:316
negative metrics:319
3 positive metrics:316
negative metrics:319
positive metrics:316
2 negative metrics:319
positive metrics:316
All help is welcome.
Related
I'm using Node.JS to run my Philips Hue lightstrip and have it match relative brightness and color temperature of the sun throughout the day, and the system is designed to run every 5 seconds and cut the program if detects a change between each loop. I achieve this through setting the color temp and brightness equal to the output of an equation where x is the current time, and obviously these return floats
I'm currently telling the program to just round to the nearest number and then set that rounded number as the temp/brightness, then record into another variable that setting (straight from the bulb, not the variable), and then next loop see if that variable matches the bulbs settings. If its different, it was manually changed so it cuts off the program so I can set the bulb to what I want
But I've had a few issues where on the next loop, before the bulb gets updated (so it should be the same value), its reading that the current settings are +-1 from the last recorded setting. And I'm wondering if this may be due to the number actually rounding in two different directions, such that when it sets the number its rounded down, but when recording the output the computer estimation actually sets it a little bit too high and rounds up instead
TL;DR: I set a value with a rounded floating point, I recorded the setting that should be the same, it ends up +-1 of the value it was supposedly set to
I found the reason, its not due to floating point errors, its because I'm using setInterval for every 5000ms, and it doesn't finish the call to the lights sometimes before it calls the next loop, leading to it adjusting the value of the lights before saving the value, so it ends up on the next loop expecting an old value. The solution is to find another way to loop every 5 seconds aside from setInterval
You need an async function instead of using setInterval.
I'm a NodeJS noob so can't be exact, but here's a javascript example that will wait 5 seconds between requests but will wait if the request doesn't resolve within 5 seconds
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function hue() {
let response = await fetch('http://url.to/hue/');
if (response.status == 200) {
let json = await response.json();
return json;
}
}
let poll = true;
while (poll) {
let lightstrip = await Promise.all([
hue().then(response => console.log(response)),
timeout(5000)
]);
}
1) I have an Androidplot XYPlot and some values are 0 to represent "no data" on that point. Can I hide these points with value "0" from the plot?
2) If I can't hide them, can I make the graph lines going from the previous point, to the 0 value point and to the next point, another color (like red) to show that this is a point "with no data"?
XYPlot's underlying model is XYSeries which uses Numbers to represent points. If you're implementing your own XYSeries then just return null from getX(i) / getY(i) where i is the index of any "no data" element.
If you're using SimpleXYSeries, then just pass null into the constructor, model or setX/Y method you're using to populate it.
When the plot is drawn, you should see your line(s) broken up where nulls are encountered.
After pondering Nicks answer I got it working:
plot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// nums is an array holding different numbers, where some are 0.
Number Nullnumber = null;
SimpleXYSeries series1test;
series1test = new SimpleXYSeries("title");
for (int j = 0; j < nums.length; j++){
if(nums[j]==0){
series1test.addLast(j, Nullnumber); // Does not display points for 0 values
//series1test.addLast(j, nums[j]); // Displays points for 0 values
} else {
series1test.addLast(j, nums[j]);
}
}
LineAndPointFormatter series1Format = new LineAndPointFormatter();
series1Format.setPointLabelFormatter(new PointLabelFormatter());
series1Format.configure(getApplicationContext(),
R.xml.line_point_formatter_with_plf1);
plot.addSeries(series1test, series1Format);
I am working in Processing and I would like to compare the color of 2 the pixels of 2 different images.
let's say we comparing the pixel in position 10
color c1= image1.pixels[10]; color c2= image2.pixels[10];
if(c1==c2) { //so something }
Firstly I was playing with brightnsess
if(brightness(c1)==brightness(c2))
Generally it was working but not exactly as I wanted as the pixels were a little bit similar but not exactly the same color.
if you want to compare colours you are probably better off comparing the three basic ones instead of the actual number that "color" is. Thus instead of
if(c1 == c2)
where you compare two large numbers like 13314249 you can go
if(red(c1) == red(c2) && green(c1) == green(c2) && blue(c1) == blue(c2))
where you compare numbers from 0 - 255, the possible values of red or green or blue you can get from a colour. As for the "little bit similar" colours, you can set a threshold and any difference below that threshold will be considered negligible thus the colours are the same. Something like this:
int threshold = 5
if(abs(red(c1) red(c2)) < threshold && abs(green(c1) - green(c2)) < threshold && abs(blue(c1) == blue(c2)) < threshold)
Remember, you have to take the absolute difference! This way, if you decrease the threshold only very similar colours are considered the same while is you increase it different colours can be considered the same. That threshold number depends on your likings!
This would also work with your brightness example...
int threshold = 5
if(abs(brightness(c1) - brightness(c2)) < threshold)
To extend on Petros's answer. Generally, when I am comparing image pixels, I normalize, so that the code will work with images that are not in standard range 0-255. It also is good when you are doing many operations on the images to keep in mind the range you are currently working with for scaling purposes.
MAX_PIXEL=255 //maybe range is different for some reason
MIN_PIXEL=0
pixel_difference = 10
threshold = pixel_difference/(MAX_PIXEL-MIN_PIXEL)
if ( abs( (brightness(c1)-brightness(c2))/(MAX_PIXEL-MIN_PIXEL))< threshold ) {
//then the pixels are similar.
}
Sometimes you can gain more ground by transforming to a difference color space.
And depending on your task at hand you can build a background model that can adapt over time or compare higher level global features such as histograms or local features such as Scale Invariant Feature Transform (SIFT), or Corners, Edges.
Given a starting hex code, I would like to know the maths to calculate the linear values of lightness in ascending and descending order. Same for Hue and Saturation.
It's kinda difficult for me to describe exactly what i want, forutnately i've found this page which make use of the exact algorithms i need:
http://www.workwithcolor.com/hsl-color-schemer-01.htm
If you checked the page you noticed that the last 3 redio buttons read: Linear by Hue, Linear by Saturation, Linear by Lightness. Each, gives you a list of hex codes in ascending order that correspond to the original hex code.
For example, for the lightness they give the following list (from color FFCE2E):
FFCE2E FFDA61 FFE694 FFF2C7 FFFEFA
I need the formulas, please.
Thanks in advance.
You can mash this up from multiple places. In a nutshell you need:
The HSL value of your picked color. Maybe this is obtained by converting an RGB to HSL (How do you get the hue of a #xxxxxx colour?) or on the website you just pick it on a palette
Now you have the 3 component (H, S, and L) and depending on which checkbox you choose, you start to decrement the component by the % value given in the edit box.
You'll obtain a list of values during this decrement and you'll now do a reverse conversion from the HSL value to the RGB (HSL to RGB color conversion).
// I gonna use rgbToHsl and hslToRgb from https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
var initialRGB = [ir, ig, ib];
var initialHSL = rgbToHsl(initialRGB[0], initialRGB[1], initialRGB[2]);
var howManyVariants = 4;
var decrementPercent = 0.1; // 10%
// This example is for hue change
var decrement = initialHSL[0] * decrementPercent;
for (var i = 0; i < howManyVariants; i++) {
// Linear decrementation
var nextHue = initialHSL[0] - i * decrement;
var nextColor = hslToRgb(nextHue, initialHSL[1], initialHSL[2]);
// visualize somehow
}
Similarly, if you want to have a set of variation by saturation then you decrement only the second parameter/component, and if you want vary luminescence, you vary the 3rd parameter.
Hope this is clear.
I have a hunch this has been done before but I am a total layman at this and don't know how to begin to ask the right question. So I will describe what I am trying to do...
I have an unknown ARGB color. I only know its absolute RGB value as displayed over two known opaque background colors, for example black 0x000000 and white 0xFFFFFF. So, to continue the example, if I know that the ARGB color is RGB 0x000080 equivalent when displayed over 0x000000 and I know that the same ARGB color is RGB 0x7F7FFF equivalent when displayed over 0xFFFFFF, is there a way to compute what the original ARGB color is?
Or is this even possible???
So, you know that putting (a,r,g,b) over (r1,g1,b1) gives you (R1,G1,B1) and that putting it over (r2,g2,b2) gives you (R2,G2,B2). In other words -- incidentally I'm going to work here in units where a ranges from 0 to 1 -- you know (1-a)r1+ar=R1, (1-a)r2+ar=R2, etc. Take those two and subtract: you get (1-a)(r1-r2)=R1-R2 and hence a=1-(R1-R2)/(r1-r2). Once you know a, you can work everything else out.
You should actually compute the values of a you get from doing that calculation on all three of {R,G,B} and average them or something, to reduce the effects of roundoff error. In fact I'd recommend that you take a = 1 - [(R1-R2)sign(r1-r2) + (G1-G2)sign(g1-g2) + (B1-B2)sign(b1-b2)] / (|r1-r2|+|g1-g2|+|b1-b2), which amounts to weighting the more reliable colours more highly.
Now you have, e.g., r = (R1-(1-a)r1)/a = (R2-(1-a)r2)/a. These two would be equal if you had infinite-precision values for a,r,g,b, but of course in practice they may differ slightly. Average them: r = [(R1+R2)-(1-a)(r1+r2)]/2a.
If your value of a happens to be very small then you'll get only rather unreliable information about r,g,b. (In the limit where a=0 you'll get no information at all, and there's obviously nothing you can do about that.) It's possible that you may get numbers outside the range 0..255, in which case I don't think you can do better than just clipping.
Here's how it works out for your particular example. (r1,g1,b1)=(0,0,0); (r2,g2,b2)=(255,255,255); (R1,G1,B1)=(0,0,128); (R2,G2,B2)=(127,127,255). So a = 1 - [127+127+127]/[255+255+255] = 128/255, which happens to be one of the 256 actually-possible values of a. (If it weren't, we should probably round it at this stage.)
Now r = (127-255*127/255)*255/256 = 0; likewise g = 0; and b = (383-255*127/255)*255/256 = 255.
So our ARGB colour was 80,00,00,FF.
Choosing black and white as the background colors is the best choice, both for ease of calculation and accuracy of result. With lots of abuse of notation....
a(RGB) + (1-a)0xFFFFFF = 0x7F7FFF
a(RGB) + (1-a)0x000000 = 0x000080
Subtracting the second from the first...
(1-a)0xFFFFFF = 0x7F7FFF-0x000080 = 0x7F7F7F
So
(1-a) = 0x7F/0xFF
a = (0xFF-0x7F)/0xFF = 0x80/0xFF
A = 0x80
and RGB = (a(RGB))/a = 0x000080/a = 0x0000FF
You can do something very similar with other choices of background color. The smaller a is and the closer the two background colors are the less accurately you will be able to determine the RGBA value. Consider the extreme cases where A=0 or where the two background colors are the same.