/
dataframe_plotter.py
52 lines (40 loc) · 1.95 KB
/
dataframe_plotter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"""The DataFramePlotter is an example of a Composable Extension for Panel
It was initially proposed by Haishiro and discussed in [Discourse 985]\
(https://discourse.holoviz.org/t/how-to-create-a-self-contained-custom-panel/985)
"""
import matplotlib.pyplot as plt
import pandas as pd
import panel as pn
import param
import seaborn as sns
class DataFramePlotter(pn.Column):
"""Extension Implementation"""
column = param.Selector()
# The _rename dict is used to keep track of Panel parameters to sync to Bokeh properties.
# As column is not a property on the Bokeh model we should set it to None
_rename = dict(pn.Column._rename, column=None)
def __init__(self, data, **params):
super().__init__(**params)
self._plot_pane = pn.pane.Matplotlib(background="blue", sizing_mode="stretch_both")
self[:] = [self.param.column, self._plot_pane]
# Please note that the alternative of setting
# @param.depends("column", watch=True)
# on _update_plot_pane does not work.
# See https://github.com/holoviz/panel/issues/1060
self.param.watch(self._update_plot_pane, "column")
columns = data.columns.values
self.param.column.objects = columns
# I need to set self.column to show a plot initially
self.column = columns[0]
# Make sure you don't use a function name already used by the Parent class.
# For example _update_model is used by the Parent Class.
def _update_plot_pane(self, _):
# - I get exception if plt.close is below ax line. See https://github.com/holoviz/panel/issues/1482
# - The plot does not change if I remove plot.close() fully.
plt.close()
ax = sns.distplot(df[self.column])
self._plot_pane.object = ax.figure
if __name__.startswith("bokeh"):
# Use the extension
df = pd.DataFrame(data={"x": [1, 2, 3, 4, 5, 6, 7], "y": [1, 2, 2, 4, 5, 9, 7]})
DataFramePlotter(df, width=300, height=300).servable()