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

Add a hex tiling glyph #4786

Closed
birdsarah opened this Issue Jul 11, 2016 · 23 comments

Comments

Projects
None yet
7 participants

@damianavila damianavila added this to the long-term milestone Jul 11, 2016

@crashMOGWAI

This comment has been minimized.

Contributor

crashMOGWAI commented Jul 11, 2016

merge with #4342

@bryevdv

This comment has been minimized.

Member

bryevdv commented Jul 12, 2016

Drawing a hex glyph would be trivial, I guess the interesting part is integrating a hex coordinate system reasonably.

@birdsarah

This comment has been minimized.

Member

birdsarah commented Jul 12, 2016

Well if it was basically a marker (so it was just an x y center) then users could figure it out for now.

Sarah Bird
sbird@continuum.io

On Jul 12, 2016, at 2:55 PM, Bryan Van de Ven notifications@github.com wrote:

Drawing a hex glyph would be trivial, I guess the interesting part is integrating a hex coordinate system reasonably.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@crashMOGWAI

This comment has been minimized.

Contributor

crashMOGWAI commented Jul 13, 2016

Would need to be more robust than a marker for feature rich binning visualizations

@bryevdv

This comment has been minimized.

Member

bryevdv commented Jul 13, 2016

@birdsarah I'm -1 on adding a hard-to-use for things-people-really-want interface, and accumulating knowledge on here, SO and the mailing list that will only have to be updated/countered/deprecated later. Offhand, I think a Hex glyphs might have:

origin = Tuple # cartesian axis coords to "anchor" hex coord system, default (0,0)

size = Float # how big the hex tiles grid is (measured along diag?)

angle = Float # global rotation about origin for the hex grid (optional)

hx = DataSpec # "hex" x coords -- should be integer only 

hy = DataSpec # "hex" y coords -- should be integer only 

This is off the top of my head. We should compare to what other systems do. Whatever we do, I think there are the same/similar problems that e.g. circles have in non 1-1 coordinate systems.

@StevenCHowell

This comment has been minimized.

Member

StevenCHowell commented Jul 17, 2016

Looking at the matplotlib and R implementation of hexbin, this seems like two separate issues:

  1. Adding a hexagon marker than can be used for representing data points
  2. Adding a hexagonal binning and plotting algorithm

The hexagonal binning and plotting algorithm could use hexagon markers/glyphs but this would likely lead to overlapping similar to issue #3315, in which histogram bars overlap. Also, it makes sense for the hexagon marker (point 1) to have a symmetric shape regardless of the plot aspect ratio. For binning and plotting data using a hexagonal grid, it would make sense to have non-symmetric hexagons which match the aspect ratio of the plot. See attached demo showing a zoomed in version of matplotlib's implementation.
screen shot 2016-07-17 at 12 54 08 pm

@crashMOGWAI

This comment has been minimized.

Contributor

crashMOGWAI commented Jul 17, 2016

Agree with @stvn66. Looks like there are a couple of ideas bouncing around that could compliment each other as incremental development goals.

  • hex glyph for data points/ markers
  • 'respect aspect' mode for hex glyph (suggested by @brevdv in #4802)
  • hex binning and plotting algorithm/ multi-purpose mesh or grid feature
@StevenCHowell

This comment has been minimized.

Member

StevenCHowell commented Jul 17, 2016

These examples from the D3 gallery show two options of visualizing a hexbin plot:

  1. Color Encoding (used for the matplotlib implementation of hexbin)
  2. Area Encoding

This second option may be more complicated to get the scaling of markers/glyphs to match the scaling of the plotting area when using different scaling for the x/y axes.

@StevenCHowell

This comment has been minimized.

Member

StevenCHowell commented Feb 22, 2017

How much overlap is there between the bokehjs in rbokeh and python bokeh? I just saw that rbokeh has hexbin plots.

@bryevdv

This comment has been minimized.

Member

bryevdv commented Feb 22, 2017

100% overlap, RBokeh uses the same BokehJS as-is. AFAIK (or have to assume) RBokeh supports hex charts by computing hexagon coordinates in R and drawing as Patches

@hafen

This comment has been minimized.

hafen commented Feb 24, 2017

That's correct.

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 16, 2018

This is obviously an old discussion but I'm interested in reviving it. I think there are two separate things, both worth doing:

  • a Hex marker, that is just an x,y,size, angle scatter marker. This should pretty trivial, ref previous work: #4827

  • HexTileglyph that draws non-overlapping hex tiles in a hex tile coordinate system.

@bryevdv bryevdv modified the milestones: long-term, 0.12.x Mar 16, 2018

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 16, 2018

I've made #7638 to describe the marker, this issue can be for the hex tiling glyph

@bryevdv bryevdv changed the title from Add a hex glyph to Add a hex tiling glyph Mar 16, 2018

@bryevdv bryevdv modified the milestones: 0.12.x, 0.12.16 Mar 17, 2018

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 23, 2018

PR coming tomorrow

screen shot 2018-03-22 at 22 00 46

@birdsarah

This comment has been minimized.

Member

birdsarah commented Mar 23, 2018

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 23, 2018

@birdsarah do you know how the larger outlined regions in your original example are specified? I could imagine a couple of possible ways to spell that but not sure if there is a standard way

@tritemio

This comment has been minimized.

tritemio commented Mar 23, 2018

In matplotlib the X-Y span is a rectangular range that is the range of the data or the regione defined by the extent keyword. Then, the keyword mincnts allows choosing a minimum count per bin for visible bins. Choosing mincnts=1, shows only bins with at least one count. The result is similar to your example. With mincnts=0 (default), hex tiles will cover a rectangular region.

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 23, 2018

@tritemio this work is not concerned with binning, and it's not clear that core bokeh itself will have any binning built in. This PR adds a basic glyph for drawing regular (data-space) hex tiles in an axial coordinate system. This is the foundation upon which a "hexbin" command might be built (e.g. by Holoviews)

For reference, the above image was generated by hand with this code:

np.random.seed(0)
n = 10000
x = 2 + 3*np.random.standard_normal(n)
y = 2 + 3*np.random.standard_normal(n)

size=0.5

x = (x - size) / (2*size);

t1 = y / size
t2 = np.floor(x + t1)
r = np.floor((np.floor(t1 - x) + t2) / 3)
q = np.floor((np.floor(2 * x + 1) + t2) / 3) - r

df = pd.DataFrame(dict(r=r.astype(int), q=q.astype(int)))
bins = df.groupby(['q', 'r']).size().reset_index(name='counts')

plot = figure(title=None, match_aspect=True, tools="hover")

source = ColumnDataSource(data=dict(
    q=bins.q,
    r=bins.r,
    c=bins.counts
))

plot.hex_tile(q="q", r="r", size=size, 
              fill_color=linear_cmap('c', Viridis256, 0, max(bins.counts)),
              line_color=None, source=source)

@tritemio

This comment has been minimized.

tritemio commented Mar 23, 2018

I see, thanks for the clarification. So this is actually a rectangular binning plotted with contiguous hex tiles. Sorry if OT, any idea or references on how to compute (not plot) the actual hex binning?

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 23, 2018

So this is actually a rectangular binning plotted with contiguous hex tiles.

No, that is not correct, the example code above is doing a real hex binning. The block of the code with floor computes the axial (q,r) integer hex coordinate of the hexagon that contains each point, then a pandas groupby bins over each (q,r) coordinate pair.

@bryevdv bryevdv removed this from the 0.12.16 milestone Mar 23, 2018

@bryevdv bryevdv added this to the 0.12.15 milestone Mar 23, 2018

@bryevdv bryevdv referenced this issue Mar 23, 2018

Merged

Hex Tiling and Binning #7682

3 of 3 tasks complete
@tritemio

This comment has been minimized.

tritemio commented Mar 23, 2018

Ops, thanks for the correction. I'll look into it more carefully!

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 24, 2018

@tritemio just as an update, I don't think that opaque code with floors is correctly doing a hex binning, at least not for the version of axial coords I am using. So we are looking to find or implement something a bit more straightforward and comprehensible

@bryevdv

This comment has been minimized.

Member

bryevdv commented Mar 27, 2018

PR is merged with API docs and some examples. User's Guide docs coming in a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment