PatrikHlobil / Pandas-Bokeh

Bokeh Plotting Backend for Pandas and GeoPandas
MIT License
879 stars 112 forks source link

Matrix plot #37

Open anki-code opened 5 years ago

anki-code commented 5 years ago

Hi! Many thanks for great solution!

Could you please add simple way to visualize pandas pivot table as rect/matrix in Bokeh?

Examples:

image

Something like this:

pt = pd.pivot_table(...)
pt.plot_bokeh.rect(...)
PatrikHlobil commented 5 years ago

Hi @anki-code , thanks for the feature request. Unfortunately, I have barely time to develop new features right now. But thanks also for the Bokeh references. I already wanted to include such a matrix scatter plot in the past, but other features/bugfixes has been more important.

If you want to implement the feature, please feel free to do so and send a PR.

Best,

Patrik

anki-code commented 5 years ago

@PatrikHlobil got it! I have some lightweight code example which could help:

# Simple version of https://bokeh.pydata.org/en/latest/docs/gallery/les_mis.html
import numpy as np
from bokeh.io import push_notebook, show, output_notebook
from bokeh.layouts import row
from bokeh.plotting import figure

df = pd.DataFrame([['A',1,2],['B',3,4],['C',5,6]], columns=['Alpha', 'Beta', 'Gamma'])
df = df.set_index('Alpha')

print(df)

def bokeh_matrix(df):
    df = df.sort_values(df.index.name, ascending=False)

    xname = []
    yname = []
    color = []
    alpha = []
    counts = np.zeros((len(df.index), len(df.columns)))

    ix = 0
    for c in df.columns:
        iy=0
        for i in df.index:
            xname.append(c)
            yname.append(i)
            alpha.append(df[c][i]/df.max().max())
            color.append('red')
            counts[iy, ix] = df[c][i]
            iy+=1
        ix+=1

    data=dict(
        xname=xname,
        yname=yname,
        colors=color,
        alphas=alpha,
        count=counts.T.flatten()
    )

    p = figure(
        title="bokeh + pandas pivot table",
        x_axis_location="above", 
        tools="hover,save",
        x_range=[str(c) for c in df.columns], 
        y_range=[str(i) for i in df.index],
        tooltips = [
            ('names', '@yname, @xname'), 
            ('count', '@count')
        ]
    )

    # p.plot_width = 800
    # p.plot_height = 800
    # p.grid.grid_line_color = None
    # p.axis.axis_line_color = None
    # p.axis.major_tick_line_color = None
    # p.axis.major_label_text_font_size = "5pt"
    # p.axis.major_label_standoff = 0
    # p.xaxis.major_label_orientation = np.pi/3

    p.rect(
        'xname', 
        'yname', 
        0.9, 
        0.9, 
        source=data,
        color='colors', 
        alpha='alphas', 
        line_color=None,
        hover_line_color='black', 
        hover_color='colors'
    )

    return p

show(bokeh_matrix(df))

Result: image