Holoviews использует поток корреляционной тепловой карты и графика регрессии

Я хочу сделать тепловую карту корреляции для DataFrame и график регрессии для каждой пары переменных. Я попытался прочитать все документы, и мне все еще очень трудно соединить два графика, чтобы при нажатии на тепловую карту мог появиться соответствующий график регрессии.

Вот пример кода:

import holoviews as hv
from holoviews import opts
import seaborn as sns
import numpy as np
import pandas as pd
hv.extension('bokeh')

df = sns.load_dataset('tips')
df = df[['total_bill', 'tip', 'size']]

corr = df.corr()
heatmap = hv.HeatMap((corr.columns, corr.index, corr))\
            .opts(tools=['tap', 'hover'], height=400, width=400, toolbar='above')

m, b = np.polyfit(df.tip, df.total_bill, deg=1)
x = np.linspace(df.tip.min(), df.tip.max())
y = m*x + b

curve = hv.Curve((x, y))\
          .opts(height=400, width=400, color='red', ylim=(0, 100))
points = hv.Scatter((df.tip, df.total_bill))

hv.Layout((points * curve) + heatmap).cols(2)

image


person steven    schedule 22.06.2019    source источник


Ответы (2)


Я скорректировал соответствующие части документов http://holoviews.org/reference/streams/bokeh/Tap.html своим кодом. Может быть, это проясняет ваше замешательство.

import pandas as pd
import numpy as np
import holoviews as hv
from holoviews import opts
hv.extension('bokeh', width=90)

import seaborn as sns

# Declare dataset
df = sns.load_dataset('tips')
df = df[['total_bill', 'tip', 'size']]

# Declare HeatMap
corr = df.corr()
heatmap = hv.HeatMap((corr.columns, corr.index, corr))

# Declare Tap stream with heatmap as source and initial values
posxy = hv.streams.Tap(source=heatmap, x='total_bill', y='tip')

# Define function to compute histogram based on tap location
def tap_histogram(x, y):
    m, b = np.polyfit(df[x], df[y], deg=1)
    x_data = np.linspace(df.tip.min(), df.tip.max())
    y_data = m*x_data + b
    return hv.Curve((x_data, y_data), x, y) * hv.Scatter((df[x], df[y]), x, y)


tap_dmap = hv.DynamicMap(tap_histogram, streams=[posxy])

(heatmap + tap_dmap).opts(
    opts.Scatter(height=400, width=400, color='red', ylim=(0, 100), framewise=True),
    opts.HeatMap(tools=['tap', 'hover'], height=400, width=400, toolbar='above'),
    opts.Curve(framewise=True)
)
person doppler    schedule 22.06.2019
comment
спасибо, дружище и очень признателен! Быстрый вопрос: какой аргумент мне следует передать, если я не хочу, чтобы тепловая карта маскировалась, когда я касаюсь или настраиваю альфа-канал маски? Я попытался найти документ, но поиск ничего не показал. - person steven; 22.06.2019
comment
nonselection_alpha=1. Когда вы ищете что-то подобное, вы всегда можете вызвать hv.help(hv.HeatMap) и т. Д. И заглянуть туда, если вы найдете аргумент, который может быть им. Документация по этим аргументам стиля есть только в документации по боке. - person doppler; 22.06.2019
comment
Есть ли способ сохранить графики как html или что-то еще, пока нажатие все еще работает, чтобы я мог поделиться с другими? Я читаю этот документ, но чувствую себя потерянным - person steven; 23.06.2019
comment
Вы не можете сохранить DynamicMaps в статический html, для них требуется запущенный процесс python (ядро вашего ноутбука, сервер боке, ...). Может быть способ имитировать то, что вы пытаетесь сделать, используя .jslink в приложении Panel, хотя это означает, что вы пишете соответствующие биты в javascript, чтобы ваш браузер мог их выполнить. - person doppler; 23.06.2019

Две общие проблемы, с которыми мы сталкиваемся при моделировании, - это коллинеарность и нелинейность. Коллинеарность можно было бы визуализировать с помощью тепловой карты корреляции, но ее было бы трудно исследовать с большим количеством переменных / функций. В следующем приложении вы можете навести указатель мыши, чтобы проверить коэффициент корреляции между любыми двумя переменными. При нажатии на диаграмму рассеяния будет добавлена ​​аппроксимированная кривая второй степени, чтобы выявить нелинейность между двумя переменными.

С помощью @doopler я немного изменил код и поделился им здесь:

import numpy as np
import pandas as pd
import holoviews as hv
hv.extension('bokeh')

# generate random data
df = pd.DataFrame(data={'col_1': np.random.normal(5, 2, 100)})

df['col_2'] = df.col_1 + np.random.gamma(5, 2, 100)
df['col_3'] = df.col_1*2 + np.random.normal(0, 10, 100)
df['col_4'] = df.col_1**2 + np.random.normal(0, 10, 100)
df['col_5'] = np.sin(df.col_1)
df['col_6'] = np.cos(df.col_1)
corr = df.corr().abs()
# mask the upper triangle of the heatmap
corr.values[np.triu_indices_from(corr, 0)] = np.nan

heatmap = hv.HeatMap((corr.columns, corr.index, corr))\
            .opts(tools=['hover'],  height=400, width=400, fontsize=9,
                  toolbar='above', colorbar=False, cmap='Blues',
                  invert_yaxis=True, xrotation=90, xlabel='', ylabel='',
                  title='Correlation Coefficient Heatmap (absolute value)')

# define tap stream with heatmap as source
tap_xy = hv.streams.Tap(source=heatmap, x='col_1', y='col_4')

# calculate correlation plot based on tap
def tap_corrplot(x, y):
    # drop missing values if there are any
    df_notnull = df[[x, y]].dropna(how='any')

    # fit a 2nd degree line/curve
    m1, m2, b = np.polyfit(df_notnull[x], df_notnull[y], deg=2)
    # generate data to plot fitted line/curve
    x_curve = np.linspace(df[x].min(), df[x].max())
    y_curve = m1*x_curve**2 + m2*x_curve+ b

    curve = hv.Curve((x_curve, y_curve), x, y)\
              .opts(color='#fc4f30', framewise=True)

    scatter = hv.Scatter((df[x], df[y]), x, y)\
                .opts(height=400, width=400, fontsize=9, size=5,
                      alpha=0.2, ylim=(df[y].min(), df[y].max()),
                      color='#30a2da', framewise=True,
                      title='Correlation Plot (2nd degree fit)')

    return curve * scatter

# map tap in heatmap with correlation plot
tap_dmap = hv.DynamicMap(tap_corrplot, streams=[tap_xy])

layout = heatmap + tap_dmap
layout

введите здесь описание изображения

Если вам нужно запустить приложение Bokeh:

from bokeh.server.server import Server

renderer = hv.renderer('bokeh')
app = renderer.app(layout)
server = Server({'/': app}, port=0)

server.start()
server.show('/')

Код хорошо работает с Jupyter Lab. Если вы используете Jupyter Notebook, проверьте эту ссылку < / а>.

person steven    schedule 11.07.2019