Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Allow multiple hatch colors in same figure #7901

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

Closed
Zaharid opened this issue Jan 20, 2017 · 19 comments
Closed

Allow multiple hatch colors in same figure #7901

Zaharid opened this issue Jan 20, 2017 · 19 comments
Labels
Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Milestone

Comments

@Zaharid
Copy link

Zaharid commented Jan 20, 2017

In version 2.0 the hatching defaults have changed. In particular, the color is always black by default and it is now inconvenient to restore the old way in which the colors are set (based on the artist line color at least for fill_between).

I'd like to request a hatchcolor parameter for the functions that accept hatches.

@Zaharid
Copy link
Author

Zaharid commented Jan 23, 2017

To make matters worse, it looks to me that the hatch color is hardcoded in the backend in such a way that it's not possible to have more than one hatch color. Therefore I don't know how to produce a figure like this with mpl2:
http://pcteserver.mi.infn.it/~nnpdf/validphys-reports/X-vnmR5BSRygX3qoK9NtFQ==/figures/norm_plot_pdfs_bard.pdf

@tacaswell tacaswell modified the milestones: 2.1 (next point release), 2.0.1 (next bug fix release) Jan 26, 2017
@tacaswell tacaswell added the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label Jan 26, 2017
@tacaswell
Copy link
Member

#7059 is roughly related

@andim
Copy link
Contributor

andim commented Jan 28, 2017

I've also encountered the same problem. It seems that PR #7415 broke what I believe should be a supported functionality, i.e. using hatching with different colors within one figure. I want to add further support for the Zaharid's suggestion of adding a kw argument for addressing this issue.

Otherwise I think it might even be preferable to revert the PR. There is a slight gain of convenience from being able to set a global default hatching color, but a net loss in functionality. (Plotting with hatch color != edgecolor could also be achieved before by plotting the artist twice once with hatching and once without.)

@tacaswell
Copy link
Member

That #7415 fixed #7166 which was hatches not showing up in the legend so it can not be reverted.

The fix for 2.0.1 could be:

  • add a set_hatch_color method to gc base with semantics of None -> get the rcParam, else use the color
  • add private _hatchcolor to the artists that know about hatches
  • when we set edge color also set _hatchcolor
  • ever place with call set_hatch we also call set_hatch_color

This will give the behavior of:

  • by default use the rcParam
  • if user explicitly set edge color use it for hatch

I want to hold off adding the hachcolor kwarg until 2.1, as that also implies adding get_hatchcolor/set_hatchcolor which is a bit much for a micro-release. There would also need to be a couple decisions made for how to 'latch' 'color', 'edgecolor', and 'hatchcolor' together

@ImportanceOfBeingErnest
Copy link
Member

I fully endorse this request to have an interface to the hatch's color, linestyle, linewidth, alpha etc. The feature to control those parameters has been present in previous versions (at least color and linewidth) and it was a big mistake to change this.

Let me elaborate a bit on the necessity of controling the hatch.
Historically hatch has been mainly used to provide an option to distinguish shapes in black/white documents, which makes it somehow understandable to tie it to the backend and hardcode the properties.
However, today most information is shared online, viewable in color and expectations for visually appealing figures is ever growing. On the other hand, figures are still printed in black and white and there is a growing awareness of the problems of limited color vision, such that at least in some areas institutions are forced to provide their information in an accessible way. As I understand it, some of the features introduced with matplotlib 2.0 were highly motivated by those requirements.
How does this relate to hatching? Hatching makes it incredibly easy to produce visually appealing and yet accessible figures.

text8119-1

Another point is of course that different styled hatching allows to add a new dimension to a figure. What is linecolor, linestyle and linewidth in 1D is patchcolor and hatch in 2D. Controlling the hatch is therefore utterly important.

@tacaswell
Copy link
Member

@ImportanceOfBeingErnest Can you open a new issue with that? That sort of effect maybe beyond the scope of what the hatching can currently do (or maybe we only need linewidth?). I think a MEP (https://github.com/matplotlib/matplotlib/tree/master/doc/devel/MEP) proposing an API for what this would look like and how to implement it across all of the backends would be well received. Given that you have clearly thought about this, can you take a crack at that?

@ImportanceOfBeingErnest
Copy link
Member

I don't think we need a new issue here, it is exactly what @Zaharid is asking for:
Getting control over hatchcolor and hatchlinewidth.
I'm saying that extending this to include alpha and hatch density would be good.

The plot from above can actually be reproduced in matplotlib 2.0 in a very hacky way. The only thing really missing here is the ability to change hatchcolor, hatchlinewidth and density via the api.

import matplotlib.pyplot as plt
import matplotlib.hatch
plt.rcParams['hatch.color'] = '#aa007d'
plt.rcParams['hatch.linewidth'] = 25

class MyHatch(matplotlib.hatch.NorthEastHatch):
    def __init__(self, hatch, density):
        # chose some parameter that give desired result
        self.num_lines = 2 
        self.num_vertices = 6

matplotlib.hatch._hatch_types.append(MyHatch)

plt.bar([1], [3], color="#000177", edgecolor="#000177",  linewidth=10)
plt.bar([2], [2], color=None, edgecolor="#770058",  linewidth=10)
# using the fact, that if hatch is not recognized, last list item is chosen.
plt.bar([2], [2], color="#770058", hatch="unknown" )

plt.savefig(__file__+".png")
plt.show()

so_hatch2_small py

@tacaswell tacaswell changed the title Add API to manage hatches Allow multiple hatch colors in same figure Feb 2, 2017
@tacaswell
Copy link
Member

Fair, I had not grasped how useful the hatch.linewidth parameter was or hacking at the underyling hatch mechanism like that. I have been working on this project for ~4 years and I still am learning more details about how it works :-p

However, your comment about how hatch selection works is not quite correct, see https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/hatch.py#L194 . It creates hatch objects for all of the hatch types it know about and merges them. It happens that MyHatch does not correctly return a null-hatch when it should. Also, your example does not work for me

hatch_test py

I would like to significantly narrow the scope of this issue to be fixing the no-multi-color-hatch regression in 2.0 and am asking for a new issue to work through all of the hatch-related knobs that will need to be added and which bits of configuration that are currently hard-coded or global parameters need to be pulled up to artist-level configuration.

@mangecoeur
Copy link

Just to chime in, there is a nice example of setting per-patch hatching color here under the 'Colors' section, which worked in 1.5 but doesn't in 2.0 .

As others have pointed out, if you want a plot that works both in color and in black and white it's critical to be able to adjust the hatch color for each patch (and eventually all sorts of other things too like width and spacing etc)

@tacaswell
Copy link
Member

@mangecoeur This should work again in 2.0.1 (fixed by #7976)

@tacaswell
Copy link
Member

(that is when we release 2.0.1)

@hughperkins
Copy link

Hi. What is preferred way to achieve colored hatch currently? Currently my graph looks like:

hatching_all_black

From reading above, it looks like:

  • colored hatching used to work, in some versoin in the past, and
  • colored hatching works again, in not-yet-released 2.0.1

Should I better:

  • rollback to an older version of matplotlib (which version?), eg using pip? , or
  • somehow install matplotlib from github master branch?

@hughperkins
Copy link

hughperkins commented Apr 1, 2017

(Ok, I rolled back to 1.5.3. That has its own issues, ie bar positioning, but fixes the hatch colors:

hatch_colored

(edit: and a quick align='center' fixes the positioning change:

aligned_and_colored

@tacaswell
Copy link
Member

@hughperkins Your understanding is correct and those are the two options. 2.0.1 should be very soon.

@kasekun
Copy link

kasekun commented May 20, 2017

Hi,
I've been dabbling with the changes to hatching as of 2.0.2. While we now have much better control of the hatch colour (Thanks!). Currently, the only way I can find to remove the background colour and allow different coloured hatching is to set color = None, alpha = 0 in the fill_between args.

The problem with this is that the legends become useless. Is there something we can use instead to mimic this behaviour without using alpha?

   # Basic example
from matplotlib import pyplot as plt
import numpy as np

h1 = '//'
d1 = np.random.rand(130)
lab1 = 'Rand1'
h2 = '\\\\'
d2 = np.random.rand(200)
lab2 = 'Rand2'

fig, ax = plt.subplots(1)

def plt_hist(axis, data, hatch, label):
	counts, edges = np.histogram(data, bins=int(len(data)**.5))
	edges = np.repeat(edges, 2)
	hist = np.hstack((0, np.repeat(counts, 2), 0))

	outline, = ax.plot(edges,hist,linewidth=1.3)		
	axis.fill_between(edges,hist,0,
				edgecolor=outline.get_color(), hatch = hatch, label=label, 
				color = None, alpha = 0)  ## < removes facecolor

plt_hist(ax,d1,h1,lab1)
plt_hist(ax,d2,h2,lab2)
ax.legend()
ax.set_ylim(0,ax.get_ylim()[1])

fill_between

@QuLogic
Copy link
Member

QuLogic commented May 20, 2017

Use facecolor='none'; don't mess with alpha.

@kasekun
Copy link

kasekun commented May 20, 2017

Ugh.... Thanks. I had futilely tried facecolor = None

@kamraaan1997
Copy link

(Ok, I rolled back to 1.5.3. That has its own issues, ie bar positioning, but fixes the hatch colors:

hatch_colored

(edit: and a quick align='center' fixes the positioning change:

aligned_and_colored

Can you please help in this plot to generate the legends where edgecolor and hatch color are different in the unfilled bar plot?

@tacaswell
Copy link
Member

@kamraaan1997 Please open a new issue with a minimal example that shows a bug or if you are looking for support on how to use Matplotlib please post your question to https://discourse.matplotlib.org . Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Projects
None yet
Development

No branches or pull requests

10 participants