Skip to content

Possible issue in hexbin using weights #20877

Closed

Description

@Enzoupi

I am facing a problem in matplotlib, using hexbin with weights (argument C=).

When I am filling the C argument, not only the ouput color changes but also the shape. Here is a very simple code snippet reproducing the behavior:

  npts = int(2e5)
  
  # Create a random distribution and another one as it perturbation
  x1 = np.random.randint(0,3000,npts)
  x2 = x1 + np.random.normal(loc=0,scale=75,size=npts)
  
  # Same for the second axis variable
  y1 = np.random.randint(280,310,npts)
  y2 = y1 + np.random.normal(loc=0,scale=2,size=npts)
  
  # Plot
  fig, axes = plt.subplots(2,1)
  ax = axes[0]
  ax.hexbin(y2-y1,x1,mincnt=1,extent=[-8,8,0,3000], gridsize=150) 
  #
  ax = axes[1]
  res = ax.hexbin(y2-y1,x1,C=x1,mincnt=1,extent=[-8,8,0,3000], gridsize=150)
  
  fig.savefig(f"hexbin_weights.png")
  plt.show()

And the corresponding output:
Snippet output

To my understanding, as the x and y coordinates of the points are identical, only the color on the two plots should change. However, it is clearly not the case. Is it another parameter that is changing without me being aware of ? Is C not doing what I expect it to do ?

Thanks in advance for any help !

Activity

  1. jklymak commented on Aug 23, 2021

    @jklymak
    Member

    Try turning mincount to 1e-6 or something else suitably small, and I think you will figure out the issue.

    I'll close because I don't think there is an error here. Please discuss at https://discourse.matplotlib.org if you would like more explanation. Thanks!

  2. Enzoupi commented on Aug 23, 2021

    @Enzoupi
    Author

    Thanks for your answer ! Although, I believe there might still be something more to say @jklymak. From the hexbin documentation it is said :

    mincnt > 0, default: None
        If not None, only display cells with more than mincnt number of points in the cell.
    

    Hence the mincnt should, to my understanding of the docstring, not depend on any of the variables (not x,y, or C). It should be the minimum number of points landing in the hexagon no ? This might be an English related problem though...

  3. jklymak commented on Aug 23, 2021

    @jklymak
    Member

    Right maybe the documentation could be clearer. Apparently when c is provided it modifies the count (or weight) of each data point. In this case you are making those counts be less than 1, and falling below the threshold.

  4. RebeccaWPerry commented on Oct 18, 2021

    @RebeccaWPerry
    Contributor

    OK if I pick this one up? I can see how an improvement to the mincnt part of the docstring would help here.

  5. jklymak commented on Oct 18, 2021

    @jklymak
    Member

    @RebeccaWPerry we don't assign PRs, so if an issue doesn't have a linked PR, anyone is welcome to work on it. If there is a linked PR, please try and work in the confines of that PR.

  6. RebeccaWPerry commented on Oct 20, 2021

    @RebeccaWPerry
    Contributor

    I looked into this more and realized it wasn't actually a documentation-only issue. I included more details in PR #21381, but for for the same of completeness here is an example that shows even when "scaling" by 1 and reducing with sum the bug persists.

    import numpy as np
    import matplotlib.pyplot as plt
    
    npts = int(2e4)
    
    # Create a random distribution and another one as it perturbation
    y = np.random.randint(0, 100, npts)
    # Y axis variable
    x = np.random.normal(loc=0, scale=2, size=npts)
    
    # Plot
    fig, axes = plt.subplots(2,1)
    
    #C not specified
    ax = axes[0]
    res1 = ax.hexbin(x, y, mincnt=1, extent=[-8,8,0,100], gridsize=150)
    
    #adding weights of 1 and specifying reduce as sum should be identical to no weights
    ax = axes[1]
    res2 = ax.hexbin(x, y, C=np.ones(len(x)), mincnt=1, extent=[-8,8,0,100], gridsize=150,
                     reduce_C_function = np.sum)
    
    c1 = res1.get_array()                
    c2 = res2.get_array()
    
    print('points binned in plot1: ', sum(c1))
    print('points binned in plot2: ', sum(c2))
    
    fig.savefig(f"hexbin_weights.png")
    plt.show()
    
  7. rcomer commented on Dec 12, 2023

    @rcomer
    Member

    With v3.8.0 and main, the code from the OP gives me

    image

    So I think this is fixed, probably by #26113.

  8. added this to the v3.8.0 milestone on Dec 12, 2023
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