Skip to content
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

Get color based on name using Enum #52

Merged
merged 34 commits into from
Aug 25, 2024

Conversation

bobleesj
Copy link
Contributor

@bobleesj bobleesj commented Aug 19, 2024

Closes #40

Motivation

We want the user to choose a color.
We do not want the user to memorize the color name.

Proposed solution

from bg_mpl_stylesheets.colors import Colors

# Get hex color code for BG_BLUE
Colors.bg_blue.value  # Example: '#0B3C5D'
Colors.bg_blue.name  # Example: 'bg_blue'

# Get a list of all bg-style colors
Colors.get_bg_colors()

@sbillinge If you find this implementation useful, I will update README.md

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good except I don't think we should update the cycler which needs to be pretty immutable or users may get unwanted behavior.

@sbillinge
Copy link
Contributor

@bobleesj please can you add a news item and update docs with this? It is really great. Ideally we would need a plot in the docs that shows the colors with the names. This is also needed to fine-tune the names.

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please see inline.


**Changed:**

* change of two colors for higher contrast: ``#AB987A`` to ``#918770`` and ``#984B43`` to ``#6C5050``
* Change of two colors for higher contrast: ``#AB987A`` to ``#918770`` and ``#984B43`` to ``#6C5050``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes it appear that colors have changed, but no colors should have changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No colors have changed. Just captialize the first alphabet from "c" to "C"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no colors have changed, please delete these change from the news.

example/color_cycle.png Outdated Show resolved Hide resolved
Copy link
Contributor Author

@bobleesj bobleesj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review my PR.

  • Updated doc with instruction
  • Updated the example image legends from hex code to color name

It appears that the CI is failing perhaps due to cache.

I checked from my own repo CI that it runs.

https://github.com/bobleesj/bg-mpl-stylesheets/actions/runs/10475957028

src/bg_mpl_stylesheets/colors.py Outdated Show resolved Hide resolved
Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bobleesj this is really great. I love what you did here. Please see my inline comments and we can move to merge this. I really like the new plot of the colors.

Thanks for uppercasing all the hex's too....


**Changed:**

* change of two colors for higher contrast: ``#AB987A`` to ``#918770`` and ``#984B43`` to ``#6C5050``
* Change of two colors for higher contrast: ``#AB987A`` to ``#918770`` and ``#984B43`` to ``#6C5050``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no colors have changed, please delete these change from the news.

src/bg_mpl_stylesheets/colors.py Outdated Show resolved Hide resolved
Copy link
Contributor Author

@bobleesj bobleesj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review @sbillinge

Again, CI passes from my forked repo:

https://github.com/bobleesj/bg-mpl-stylesheets/actions/runs/10479038124

  • properties lower_cased instead of lower-cased since it's a property.
  • news on color change removed.

README.rst Outdated Show resolved Hide resolved
src/bg_mpl_stylesheets/colors.py Show resolved Hide resolved
assert hex == expected_hex


@pytest.mark.parametrize(
Copy link
Contributor Author

@bobleesj bobleesj Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, get_color_name(hex) could instead return a string of bg-color instead of bg_color but the user probably would be storing the color name string and use that to get the hex code (maybe)

Keeping all lower_cased would be a simple solution for all. @sbillinge Do you agree?

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, one last thing on the news.

@@ -4,7 +4,6 @@

**Changed:**

* Change of two colors for higher contrast: ``#AB987A`` to ``#918770`` and ``#984B43`` to ``#6C5050``
* Capitalized the hex color codes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be under fixed. Changed refers to changes that would affect the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be under fixed. Changed refers to changes that would affect the user.

Noted. Moved and please review.

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. one comment again...

news/colorupdate.rst Outdated Show resolved Hide resolved
Copy link
Contributor Author

@bobleesj bobleesj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review!

news/colorupdate.rst Show resolved Hide resolved
@sbillinge
Copy link
Contributor

It looks like the problem is a lower case b in
'axes.prop_cycle': cycler('color', ['#0B3C5D', '#B82601', '#1C6B0A', '#328CC1', '#A8b6C1', '#D9B310', '#6C5050', '#76323F', '#626E60', '#918770', '#C09F80', '#B0B0B0FF']),

@bobleesj
Copy link
Contributor Author

!! @sbillinge thanks

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few comments that could help the usability

for color in cls:
if color.value.lower() == hex_value.lower():
return color.name
raise ValueError("Unknown color name. Please check Colors enum for available colors.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would a non programmer user know how to do this? I think this is too jargony to be helpful.

Copy link
Contributor Author

@bobleesj bobleesj Aug 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this?

raise ValueError("You have entered an unknown color hex value."
                         " Please check the src/bg_mpl_stylesheets/colors.py file for the available colors.")

You have entered an unknown color hex value -> reason for the error
Please check the src/bg_mpl_stylesheets/colors.py file for the available colors -> what to do fix to it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, much better error message. Even better would be a method that lists the available colors maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, we already have that method, so could we mention that in the error message as an option? Look in the file or run that method?

README.rst Show resolved Hide resolved
Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a few more thoughts to make this more usable? Not sure what you think.

# Add more colors as needed

@classmethod
def get_color_name(cls, hex_value: str) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need these. It seems that we are not making the best use of enums. For example, for usage, wouldn't something like this be cleaner?:

 import bg_mpl_stylesheets.colors.Colors as bgcolors

for color in bg.colors:
    ax.plot(x, y + offset * i, label=color.name, color=color.value, linestyle="-")

and if we want to address explicitly, something like

bgblue = bgcolors.bg_blue
ax.plot(x, y + offset * i, label=bgblue.name, color=bgblue.value, linestyle="-")

I see that we would need the hex to name converter when using the cycler as a cycle unless we could figure out how to make the cycler elements the enum values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class Colors(str, Enum):
    bg_blue = "#0B3C5D"
    bg_red = "#B82601"
    bg_green = "#1C6B0A"
    bg_light_blue = "#328CC1"
    bg_light_grey = "#A8B6C1"
    bg_yellow = "#D9B310"
    bg_brown = "#6C5050"
    bg_burgundy = "#76323F"
    bg_olive_green = "#626E60"
    bg_muted_olive = "#918770"
    bg_beige = "#C09F80"
    bg_grey = "#B0B0B0FF"

Right, this would be it based on your suggestion above.

The purpose of get_color_name was for testing below and changing the legends from hex to color names:

In the example code under example/color_cycles.py, we are testing the hard coded bg-style.

Screenshot 2024-08-21 at 4 49 11 PM
cycle = plt.rcParams["axes.prop_cycle"].by_key()["color"]

# plot the color cycles and corresponding color codes.
for i, hex in enumerate(cycle):
    color_name = Colors.get_color_name(hex)
    ax.plot(x, y + offset * i, label=color_name, color=hex, linestyle="-")

If do not have the get_color_name class method, then we do not have access to the color name since the hex a string.

If retrieving the color name from a string is not needed (legends for the the example code), then, we can remove get_color_name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to get that figure as it is but without the get_color_name method but using the enum properties? That may be true, but something like replacing the hex hard code with the enum values could fix it? It is still "immutable" in the way that someone could extend the colors enum and it wouldn't change the cycler (which is what we seek for the immutability). We could also test it with hard coded hex's so if someone changes the hex of one of the used enums the test would break.

@bobleesj
Copy link
Contributor Author

I will address the comments later in the afternoon and see how we can make this package useful.

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please see comments. I have to hop on a flight. I will look at more later.

README.rst Outdated
bg_blue_hex = Colors.bg_blue.value

# Get color name
bg_blue_name = Colors.bg_blue.name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we are teaching people somewhat ugly coding practices so I would remove these bg_blue_hex etc. variables.

We do want to let people know how to access the name and hex values, but let's do that with words, not with bad code....

The beauty of the enum is how easy and pythonic it is to access the names and values.

I am not totally sure why we don't use a dict, but it is ok

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup value and name directly accessed in the example.

@bobleesj
Copy link
Contributor Author

please see comments. I have to hop on a flight. I will look at more later.

Safe flight. I'll give this some thought and address them in the afternoon.

Copy link
Contributor Author

@bobleesj bobleesj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbillinge Please review!

ax.plot(x, y + offset * i, label="\\{}".format(c), color=c, linestyle="-")

for i, hex in enumerate(cycle):
ax.plot(x, y + offset * i, label=Colors(hex).name, color=hex, linestyle="-")
Copy link
Contributor Author

@bobleesj bobleesj Aug 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no way to get that figure as it is but without the get_color_name method but using the enum properties? That may be true, but something like replacing the hex hard code with the enum values could fix it? It is still "immutable" in the way that someone could extend the colors enum and it wouldn't change the cycler (which is what we seek for the immutability). We could also test it with hard coded hex's so if someone changes the hex of one of the used enums the test would break.

@sbillinge You are correct.

I found out that we do not need get_color_name. Python's enum provides Colors(hex).name where we can get the property variable name from a string. Didn't know about this feature but certainly saved many lines of code.

@sbillinge sbillinge merged commit abdf6fa into Billingegroup:main Aug 25, 2024
3 checks passed
@sbillinge
Copy link
Contributor

Lovely @bobleesj, Thanks so much!

@bobleesj bobleesj deleted the color-select branch August 25, 2024 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

create bg-colorlist
2 participants