You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
there was already a pull request one month ago here: #1676
but it seems to be stuck. @RaghavPrabhakar66 : Feel free to review this pr, or, in case that you have another idea, you can also make a new pr
@kolibril13 I reviewed PR #1676, it works but I don't think we need if-else code statement, we can do it directly also.
Like rng = random.Random(random_seed).
Some Experiments:
Hey, I have reviewed that PR already a while ago, but the fundamental issue noted in #1676 (comment) has not been discussed or resolved yet. Removing the if-else will also not change that.
I don't think that this behavior is expected, but I also don't really have a good / simple solution for this. I think that essentially, we'd have to check whether a RNG with the given seed has already been initialized, and then use the existing one – or create one.
I don't know if I understood it correctly. What is the expected behavior? Is it if random.Random() is already defined with random_seed then no need to create RNG Object and If not then, we create RNG Object and set it's seed to random_seed.
I looked into it and I don't think its possible with python random module. Random does give us function such getstate() and setstate() which can be used to get info on its current state. getstate() function returns a list of size 624 and I dont think we can extract seed from that.
But it also changes after some tries, so we can't determine the seed. I found something on stackoverflow related to it:
In summary on np.random.seed(s):
- get_state()[1][0] immediately after setting: retrieves s that exactly recreates the state
- get_state()[1][0] after generating numbers: may or may not retrieve s, but it will not recreate the current state (at get_state())
- get_state()[1][0] after generating many numbers: will not retrieve s. This is because pos exhausted its representation.
- get_state() at any point: will exactly recreate that point. Lastly, behavior may also differ due to get_state()[3:] (and of course [0]).
So, I don't think we can retrieve current Random seed as the seed is used to update the internal state of the random number generator is not directly stored anywhere.
Before we get into implementation details, we have to agree on what kind of behavior we should actually expect. Personally, I think that a situation like
is not desireable, because setting the seed then is equivalent to hard-coding one specific color. I would expect that repeatedly calling random_color(random_seed=42) continues to give random colors, but in a reproducible way.
You are right that the current seed of an initialized RNG cannot be retrieved -- but as it is mentioned in the SO answers you've posted, we can still store the seed of the RNG that has been initialized last somewhere. (Maybe in Manim's configuration, maybe "just" in the module; not sure about that.) Then, when random_color is called again, the passed seed can be compared to the stored one, and either the already initialized RNG can be used, or a new one can be initialized.
Yeah, we can store seed in config file and compare it if users provide random_seed.
I would expect that repeatedly calling random_color(random_seed=42) continues to give random colors, but in a reproducible way.
I was thinking maybe we could use getstate() and setstate() functions. Like we could return the state of seed at that with getstate() and later on set it back to its previous state using setstate().
In the meanwhile, I can try working on storing it in config system.
just an additional comment: I'd suggest a parameter to exclude either certain colors or at least to optionally automatically exclude the current background color.
That's a good point. I imagine re-rendering something until you get an actually visible color gets more difficult as you work with more colors. Actually, wouldn't the function have to exclude a range of very similar colors to avoid that situation?
That's a good point. I imagine re-rendering something until you get an actually visible color gets more difficult as you work with more colors. Actually, wouldn't the function have to exclude a range of very similar colors to avoid that situation?
I don't think so, since it anyway are not too many different colors from which the random colors are drawn - but It would probably not too difficult to find similar colors to exclude using hue and brightness.
I think that goes beyond the scope of this issue, but it does sound like enough of a concern to deserve its own issue. I'm not too sure though. What do you think?
I think that goes beyond the scope of this issue, but it does sound like enough of a concern to deserve its own issue. I'm not too sure though. What do you think?
I am just thinking that it would be easiest to implement these things at the same time rather than doing surgery on this code several times in a row. And I also think that just excluding the current background is "good enough" - I reverted to random_bright_color() on a dark background, but the contrast between the different shades is very weak.
I think that goes beyond the scope of this issue, but it does sound like enough of a concern to deserve its own issue. I'm not too sure though. What do you think?
I am just thinking that it would be easiest to implement these things at the same time rather than doing surgery on this code several times in a row. And I also think that just excluding the current background is "good enough" - I reverted to random_bright_color() on a dark background, but the contrast between the different shades is very weak.
Would you like to clarify what you mean by excluding "background" ? As per the color PR it uses the manim core colors for random colors. Or like the basic manim colors
So the current goal of this issue becomes changing the behavior with the seed but I also think that the exclusion of a specific color range shouldn't be done in this. Because in the end it gets more complicated if you want to have a magic function which basically computes legible colors if you specify a background i actually think that one should be separate if we want to do it right we need to do some research what that actually means.
Because just excluding the exact background color won't really help in that situation even if i see where this comes from. But i think we should just stick to the seed for this ticket, so then yes we have to work on it twice but at least we do it right!
I have a suggestion here - I created a small RandomColor object which contains its own instance of a random number generator which can be seeded and functions to pick a random color from a given set of colors, a color with a different hue from a given reference color or saturation/value or saturation/lightness pair.
Activity
behackl commentedon Jun 12, 2021
The link you have posted regarding the numpy random seed doesn't really apply for the
random_color
function, it doesn't use numpy's random module.kolibril13 commentedon Jun 13, 2021
True, sorry!
I got confused, because there is also a
choise
function in numpy.Here is the correct one:
https://docs.python.org/3/library/random.html#bookkeeping-functions
RaghavPrabhakar66 commentedon Jul 20, 2021
Hi, Can I take this issue?
kolibril13 commentedon Jul 20, 2021
there was already a pull request one month ago here: #1676
but it seems to be stuck.
@RaghavPrabhakar66 : Feel free to review this pr, or, in case that you have another idea, you can also make a new pr
RaghavPrabhakar66 commentedon Jul 20, 2021
@kolibril13 I reviewed PR #1676, it works but I don't think we need if-else code statement, we can do it directly also.
Like
rng = random.Random(random_seed)
.Some Experiments:
So should I create a new pr?
behackl commentedon Jul 20, 2021
Hey, I have reviewed that PR already a while ago, but the fundamental issue noted in #1676 (comment) has not been discussed or resolved yet. Removing the if-else will also not change that.
RaghavPrabhakar66 commentedon Jul 20, 2021
I don't know if I understood it correctly. What is the expected behavior? Is it if
random.Random()
is already defined withrandom_seed
then no need to createRNG Object
and If not then, we createRNG Object
and set it's seed torandom_seed
.I looked into it and I don't think its possible with python random module. Random does give us function such
getstate()
andsetstate()
which can be used to get info on its current state.getstate()
function returns a list of size624
and I dont think we can extract seed from that.Though this can be done in
Numpy
random module asnp.random.get_state()[1][0]
returnsrandom_seed
.But it also changes after some tries, so we can't determine the seed. I found something on stackoverflow related to it:
So, I don't think we can retrieve current Random seed as the seed is used to update the internal state of the random number generator is not directly stored anywhere.
References:
behackl commentedon Jul 20, 2021
Before we get into implementation details, we have to agree on what kind of behavior we should actually expect. Personally, I think that a situation like
is not desireable, because setting the seed then is equivalent to hard-coding one specific color. I would expect that repeatedly calling
random_color(random_seed=42)
continues to give random colors, but in a reproducible way.You are right that the current seed of an initialized RNG cannot be retrieved -- but as it is mentioned in the SO answers you've posted, we can still store the seed of the RNG that has been initialized last somewhere. (Maybe in Manim's configuration, maybe "just" in the module; not sure about that.) Then, when
random_color
is called again, the passed seed can be compared to the stored one, and either the already initialized RNG can be used, or a new one can be initialized.RaghavPrabhakar66 commentedon Jul 21, 2021
Yeah, we can store seed in config file and compare it if users provide
random_seed
.I was thinking maybe we could use
getstate()
andsetstate()
functions. Like we could return the state of seed at that withgetstate()
and later on set it back to its previous state usingsetstate()
.In the meanwhile, I can try working on storing it in config system.
hickmott99 commentedon Apr 18, 2022
Has anyone closed this issue? Can I tackle it? @RaghavPrabhakar66 @behackl
5 remaining items
uwezi commentedon Sep 4, 2023
just an additional comment: I'd suggest a parameter to exclude either certain colors or at least to optionally automatically exclude the current background color.
KaylaMLe commentedon Sep 4, 2023
That's a good point. I imagine re-rendering something until you get an actually visible color gets more difficult as you work with more colors. Actually, wouldn't the function have to exclude a range of very similar colors to avoid that situation?
uwezi commentedon Sep 4, 2023
I don't think so, since it anyway are not too many different colors from which the random colors are drawn - but It would probably not too difficult to find similar colors to exclude using hue and brightness.
KaylaMLe commentedon Sep 4, 2023
I think that goes beyond the scope of this issue, but it does sound like enough of a concern to deserve its own issue. I'm not too sure though. What do you think?
uwezi commentedon Sep 4, 2023
I am just thinking that it would be easiest to implement these things at the same time rather than doing surgery on this code several times in a row. And I also think that just excluding the current background is "good enough" - I reverted to
random_bright_color()
on a dark background, but the contrast between the different shades is very weak.KaylaMLe commentedon Sep 4, 2023
Sounds good. I'm not experienced enough with Manim to really know how dificult/easy using these functions are
MrDiver commentedon Sep 4, 2023
Would you like to clarify what you mean by excluding "background" ? As per the color PR it uses the manim core colors for random colors. Or like the basic manim colors
MrDiver commentedon Sep 5, 2023
Nvm.
So the current goal of this issue becomes changing the behavior with the seed but I also think that the exclusion of a specific color range shouldn't be done in this. Because in the end it gets more complicated if you want to have a magic function which basically computes legible colors if you specify a background i actually think that one should be separate if we want to do it right we need to do some research what that actually means.
Because just excluding the exact background color won't really help in that situation even if i see where this comes from. But i think we should just stick to the seed for this ticket, so then yes we have to work on it twice but at least we do it right!
MrDiver commentedon Sep 5, 2023
https://www.uxmatters.com/mt/archives/2007/01/applying-color-theory-to-digital-displays.php
uwezi commentedon Sep 9, 2023
I have a suggestion here - I created a small
RandomColor
object which contains its own instance of a random number generator which can be seeded and functions to pick a random color from a given set of colors, a color with a different hue from a given reference color or saturation/value or saturation/lightness pair.usage:
uwezi commentedon Sep 9, 2023
Ok I continued to work on it, ready to suggest a pull-request, after some additional polishing. What does everyone/anyone think?
rndcol = RandomColor(seed=42)
initializes an instance with its own random number seedrndcol.randomColor()
same as the current plainrandom_color()
rndcol.setPalette([RED,GREEN,BLUE,YELLOW])
sets an internal color palette for random choicerndcol.randomPaletteColor(allow_repeat=False)
picks a random color from the palette, avoiding immediate repetitionsrndcol.randomContrastColor(PURE_BLUE))
tries to pick contrasting colors with regard to hue, saturation and brightnessrndcol.randomHue(RED))
generates a random color with same saturation and brightness, but random huerandom_color
method to produce colors deterministically #4265