FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[ENH]: Different edgecolor and hatch color in bar plot · Issue #26074 · matplotlib/matplotlib · GitHub

Repository navigation

[ENH]: Different edgecolor and hatch color in bar plot #26074

Closed

Description

Problem

Colored edges look ugly:

I want bars with black edges and colored hatch:

My current workaround is to draw the bars twice, once with colored hatch and then a second time only with black edges:

import matplotlib.pyplot as plt
import numpy as np

width = 0.35
x = np.arange(4) + 1
y_red = [1, 3, 1, 4]
y_blue = [2, 2, 4, 1]

plt.bar(x - 0.5 * width, y_red, width, label="Height of red bars", hatch="////", facecolor=(0, 0, 0, 0), edgecolor="red")
plt.bar(x - 0.5 * width, y_red, width, facecolor=(0, 0, 0, 0), edgecolor="black")

plt.bar(x + 0.5 * width, y_blue, width, label="Height of blue bars", hatch=r"\\", facecolor=(0, 0, 0, 0), edgecolor="blue")
plt.bar(x + 0.5 * width, y_blue, width, facecolor=(0, 0, 0, 0), edgecolor="black")

plt.xticks(x)
plt.yticks([0, 1, 2, 3, 4])
plt.legend()
plt.savefig("hatch.png")
plt.show()

This workaround is not optimal because the legend is wrong.

Proposed solution

I propose a hatchcolor parameter which is independent of edgecolor.

Activity

  1. oscargus commented on Jun 5, 2023

    Member

    There is partial support for this in the code base. The backends support a separate hatch color and collections store the hatch color as self._hatch_color. There is also an rcParam hatch.color that can be used (but will be overwritten if edgecolor is set).

    If anyone wants to give it a go, please remember that it cannot break the current behavior. I assume adding a keyword argument to bar which is None by default and is only used when set is the way to go. This will mean that hatch.color will still not be used when edgecolor is set.

    There is also a (long-term) idea to completely rework the hatch handling by introducing "hatch styles", but no one has had the time to do this.

  2. 99991 commented on Jun 5, 2023

    Author

    The backends support a separate hatch color and collections store the hatch color as self._hatch_color.

    Thank you for the hint! It has helped me to find the following workaround that meets my requirements. I am unsure whether to leave this issue open in case someone wants to implement a "proper" solution.

    import matplotlib.pyplot as plt
    import numpy as np
    
    width = 0.35
    x = np.arange(4) + 1
    y_red = [1, 3, 1, 4]
    y_blue = [2, 2, 4, 1]
    
    collection = plt.bar(x - 0.5 * width, y_red, width, label="Height of red bars", hatch="////", facecolor=(0, 0, 0, 0), edgecolor="black")
    for patch in collection.patches:
        patch._hatch_color = (1.0, 0.0, 0.0, 1.0)
    
    collection = plt.bar(x + 0.5 * width, y_blue, width, label="Height of blue bars", hatch=r"\\", facecolor=(0, 0, 0, 0), edgecolor="black")
    for patch in collection.patches:
        patch._hatch_color = (0.0, 0.0, 1.0, 1.0)
    
    plt.xticks(x)
    plt.yticks([0, 1, 2, 3, 4])
    plt.legend()
    plt.savefig("hatch.png")
    plt.show()

  3. story645 commented on Jun 5, 2023

    Member

    I assume adding a keyword argument to bar which is None by default and is only used when set is the way to go

    Um, if we do this (and I'm very pro, edit: give or take a proper hatch API), I think it should be a keyword on patch and propagated up

  4. artemshekh commented on Jun 22, 2023

    Contributor

    What is a logic behind this code?

    def _set_edgecolor(self, color):
    set_hatch_color = True
    if color is None:
    if (mpl.rcParams['patch.force_edgecolor'] or
    not self._fill or self._edge_default):
    color = mpl.rcParams['patch.edgecolor']
    else:
    color = 'none'
    set_hatch_color = False

    'set_hatch_color = False' allows to change simultaneously hatchcolor through rcParams and edgecolor.

  5. Vashesh08 commented on Sep 3, 2023

    Contributor

    I have worked on this issue. Please review it

    import matplotlib.pyplot as plt
    import numpy as np
    
    width = 0.35
    x = np.arange(4) + 1
    y_red = [1, 3, 1, 4]
    y_blue = [2, 2, 4, 1]
    
    plt.bar(x - 0.5 * width, y_red, width, label="Height of red bars", hatch="////", facecolor=(0, 0, 0, 0), edgecolor="black", hatchcolor="red")
    
    plt.bar(x + 0.5 * width, y_blue, width, label="Height of blue bars", hatch=r"\\", facecolor=(0, 0, 0, 0), edgecolor="black", hatchcolor="blue")
    
    plt.xticks(x)
    plt.yticks([0, 1, 2, 3, 4])
    plt.legend()
    plt.savefig("hatch.png")
    plt.show()
    

    The code can be edited in the following way to provide a different hatchcolor and edgecolor

  6. 99991 commented on Sep 3, 2023

    Author

    I have worked on this issue. Please review it

    I got the following error with your latest commit at the time, but it seems that new commits are still being made.

    python3 example.py 
    Traceback (most recent call last):
      File "/data/example.py", line 9, in <module>
        plt.bar(x - 0.5 * width, y_red, width, label="Height of red bars", hatch="////", facecolor=(0, 0, 0, 0), edgecolor="black", hatchcolor="red")
      File "/data/lib/matplotlib/pyplot.py", line 2686, in bar
        return gca().bar(
      File "/data/lib/matplotlib/__init__.py", line 1465, in inner
        return func(ax, *map(sanitize_sequence, args), **kwargs)
      File "/data/lib/matplotlib/axes/_axes.py", line 2528, in bar
        r._internal_update(kwargs)
      File "/data/lib/matplotlib/artist.py", line 1218, in _internal_update
        return self._update_props(
      File "/data/lib/matplotlib/artist.py", line 1192, in _update_props
        raise AttributeError(
    AttributeError: Rectangle.set() got an unexpected keyword argument 'hatchcolor'
    
  7. Vashesh08 commented on Sep 3, 2023

    Contributor

    Hi Thomas @99991 , can you try again Issue26074 branch and try. I already resolved this issue before pushing in the first commit.

    In the newer commits, I am just solving the flaky issues (like empty line with extra whitespace) .

  8. 99991 commented on Sep 3, 2023

    Author

    I was able to successfully run your code with this branch. It produced a satisfactory hatched bar plot. The legend is correct as well.

  9. Vashesh08 commented on Sep 3, 2023

    Contributor

    I'm not sure why the PR did not show the changes earlier. Maybe all commits were not pushed. If anyone can go through it again, it would be great. Thanks!

    It shows in the PR that it is connected with the same branch.(Attached Screenshot)

  10. matchyc commented on Feb 2, 2024

    @Vashesh08 Great PR, reviewers should review this code, and this function should be merged into matplotlib.

  11. added this to the v3.11.0 milestone on Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL