0
# Parameter Integration
1
2
Integration with the Param library for creating reactive UIs from parameterized classes and managing parameter dependencies. This system enables automatic UI generation, reactive programming patterns, and seamless integration between Panel components and Param-based models.
3
4
## Capabilities
5
6
### Automatic UI Generation
7
8
Generate user interfaces automatically from parameterized classes with appropriate widgets for each parameter type.
9
10
```python { .api }
11
class Param:
12
"""
13
Auto-generate UI from Parameterized class with widgets for each parameter.
14
15
Parameters:
16
- object: Parameterized class instance to create UI for
17
- parameters: List of parameter names to include (default: all)
18
- widgets: Dict mapping parameter names to specific widget types
19
- show_labels: Whether to show parameter labels
20
- show_name: Whether to show the class name
21
- **params: Additional parameters
22
"""
23
```
24
25
### Reactive Expressions
26
27
Create reactive expressions that automatically update when parameter values change.
28
29
```python { .api }
30
class ReactiveExpr:
31
"""
32
Reactive expression component that updates automatically.
33
34
Parameters:
35
- object: Function or expression to evaluate reactively
36
- **params: Additional parameters
37
"""
38
```
39
40
### Parameter References
41
42
Reference and bind to specific parameters for creating reactive dependencies.
43
44
```python { .api }
45
class ParamRef:
46
"""
47
Parameter reference for creating reactive bindings.
48
49
Parameters:
50
- object: Parameterized object containing the parameter
51
- parameter: Name of parameter to reference
52
- **params: Additional parameters
53
"""
54
55
class ParamFunction:
56
"""
57
Function parameter reference for method binding.
58
59
Parameters:
60
- function: Function to reference
61
- **params: Additional parameters
62
"""
63
64
class ParamMethod:
65
"""
66
Method parameter reference for instance method binding.
67
68
Parameters:
69
- instance: Object instance containing the method
70
- method: Method name to reference
71
- **params: Additional parameters
72
"""
73
```
74
75
## Usage Examples
76
77
### Basic Parameter UI Generation
78
79
```python
80
import panel as pn
81
import param
82
83
class Settings(param.Parameterized):
84
"""Application settings with various parameter types"""
85
86
title = param.String(default="My App", doc="Application title")
87
theme = param.Selector(default='light', objects=['light', 'dark'], doc="UI theme")
88
max_items = param.Integer(default=100, bounds=(1, 1000), doc="Maximum items to display")
89
enable_debug = param.Boolean(default=False, doc="Enable debug mode")
90
refresh_rate = param.Number(default=1.0, bounds=(0.1, 10.0), doc="Refresh rate in seconds")
91
created_date = param.Date(default=datetime.date.today(), doc="Creation date")
92
93
settings = Settings()
94
95
# Auto-generate UI from parameters
96
settings_ui = pn.Param(
97
settings,
98
parameters=['title', 'theme', 'max_items', 'enable_debug', 'refresh_rate'],
99
widgets={
100
'title': pn.widgets.TextInput,
101
'refresh_rate': {'type': pn.widgets.FloatSlider, 'step': 0.1}
102
},
103
show_labels=True,
104
show_name=True
105
)
106
```
107
108
### Custom Widget Mapping
109
110
```python
111
class DataAnalysis(param.Parameterized):
112
113
dataset = param.Selector(default='iris', objects=['iris', 'titanic', 'boston'])
114
columns = param.ListSelector(default=[], objects=[])
115
plot_type = param.Selector(default='scatter', objects=['scatter', 'line', 'bar', 'histogram'])
116
color_by = param.String(default='')
117
118
@param.depends('dataset', watch=True)
119
def _update_columns(self):
120
# Update available columns based on dataset
121
if self.dataset == 'iris':
122
self.param.columns.objects = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
123
# ... update for other datasets
124
125
analysis = DataAnalysis()
126
127
# Create UI with custom widgets
128
analysis_ui = pn.Param(
129
analysis,
130
widgets={
131
'dataset': pn.widgets.RadioButtonGroup,
132
'columns': pn.widgets.CheckBoxGroup,
133
'plot_type': {'type': pn.widgets.Select, 'width': 200},
134
'color_by': pn.widgets.AutocompleteInput
135
}
136
)
137
```
138
139
### Reactive Programming with Dependencies
140
141
```python
142
import param
143
import pandas as pd
144
import matplotlib.pyplot as plt
145
146
class InteractivePlot(param.Parameterized):
147
148
x_column = param.Selector()
149
y_column = param.Selector()
150
color_column = param.Selector(default=None, allow_None=True)
151
plot_type = param.Selector(default='scatter', objects=['scatter', 'line', 'bar'])
152
153
def __init__(self, df, **params):
154
self.df = df
155
# Set parameter options from DataFrame columns
156
columns = list(df.columns)
157
self.param.x_column.objects = columns
158
self.param.y_column.objects = columns
159
self.param.color_column.objects = [None] + columns
160
super().__init__(**params)
161
162
# Set default values
163
if len(columns) >= 2:
164
self.x_column = columns[0]
165
self.y_column = columns[1]
166
167
@param.depends('x_column', 'y_column', 'color_column', 'plot_type')
168
def create_plot(self):
169
"""Reactive method that updates when parameters change"""
170
if not self.x_column or not self.y_column:
171
return pn.pane.HTML("<p>Please select X and Y columns</p>")
172
173
fig, ax = plt.subplots(figsize=(8, 6))
174
175
if self.plot_type == 'scatter':
176
scatter = ax.scatter(
177
self.df[self.x_column],
178
self.df[self.y_column],
179
c=self.df[self.color_column] if self.color_column else 'blue',
180
alpha=0.6
181
)
182
if self.color_column:
183
plt.colorbar(scatter, ax=ax, label=self.color_column)
184
185
elif self.plot_type == 'line':
186
ax.plot(self.df[self.x_column], self.df[self.y_column])
187
188
elif self.plot_type == 'bar':
189
ax.bar(self.df[self.x_column], self.df[self.y_column])
190
191
ax.set_xlabel(self.x_column)
192
ax.set_ylabel(self.y_column)
193
ax.set_title(f'{self.plot_type.title()} Plot: {self.y_column} vs {self.x_column}')
194
195
return pn.pane.Matplotlib(fig, tight=True)
196
197
# Create interactive plot
198
df = pd.read_csv('data.csv')
199
plot_app = InteractivePlot(df)
200
201
# Create reactive layout
202
layout = pn.Row(
203
pn.Param(plot_app, width=300),
204
plot_app.create_plot,
205
sizing_mode='stretch_height'
206
)
207
```
208
209
### Advanced Parameter Binding
210
211
```python
212
class Dashboard(param.Parameterized):
213
214
data_source = param.Selector(default='live', objects=['live', 'historical', 'simulated'])
215
refresh_interval = param.Integer(default=5, bounds=(1, 60))
216
auto_refresh = param.Boolean(default=True)
217
218
def __init__(self, **params):
219
super().__init__(**params)
220
self.data = pd.DataFrame()
221
self.setup_periodic_refresh()
222
223
def setup_periodic_refresh(self):
224
"""Setup automatic data refresh based on parameters"""
225
def refresh_data():
226
if self.auto_refresh:
227
self.data = self.fetch_data()
228
return self.create_visualization()
229
return pn.pane.HTML("<p>Auto-refresh disabled</p>")
230
231
# Create periodic callback
232
self.refresh_callback = pn.state.add_periodic_callback(
233
refresh_data,
234
period=self.refresh_interval * 1000
235
)
236
237
@param.depends('data_source')
238
def fetch_data(self):
239
"""Fetch data based on selected source"""
240
if self.data_source == 'live':
241
return self.get_live_data()
242
elif self.data_source == 'historical':
243
return self.get_historical_data()
244
else:
245
return self.generate_simulated_data()
246
247
@param.depends('refresh_interval', watch=True)
248
def update_refresh_rate(self):
249
"""Update periodic callback when refresh interval changes"""
250
if hasattr(self, 'refresh_callback'):
251
pn.state.remove_periodic_callback(self.refresh_callback)
252
self.setup_periodic_refresh()
253
254
def create_visualization(self):
255
"""Create visualization from current data"""
256
if self.data.empty:
257
return pn.pane.HTML("<p>No data available</p>")
258
259
return pn.pane.DataFrame(self.data.head(10))
260
261
dashboard = Dashboard()
262
263
# Create UI with parameter controls and reactive display
264
app = pn.Column(
265
"# Live Dashboard",
266
pn.Param(dashboard, parameters=['data_source', 'refresh_interval', 'auto_refresh']),
267
pn.bind(dashboard.create_visualization)
268
)
269
```
270
271
### Parameter Validation and Constraints
272
273
```python
274
class FormValidator(param.Parameterized):
275
276
name = param.String(default="", regex=r'^[A-Za-z\s]+$')
277
email = param.String(default="", regex=r'^[^@]+@[^@]+\.[^@]+$')
278
age = param.Integer(default=18, bounds=(13, 120))
279
password = param.String(default="")
280
confirm_password = param.String(default="")
281
282
@param.depends('password', 'confirm_password', watch=True)
283
def validate_passwords(self):
284
if self.password != self.confirm_password:
285
self.param.confirm_password.constant = False
286
# Show validation error
287
else:
288
self.param.confirm_password.constant = True
289
290
def is_valid(self):
291
"""Check if all parameters are valid"""
292
try:
293
self.param.name.validate(self.name)
294
self.param.email.validate(self.email)
295
self.param.age.validate(self.age)
296
return self.password == self.confirm_password and len(self.password) >= 8
297
except ValueError:
298
return False
299
300
validator = FormValidator()
301
302
# Create form with validation
303
form_ui = pn.Param(
304
validator,
305
widgets={
306
'password': pn.widgets.PasswordInput,
307
'confirm_password': pn.widgets.PasswordInput
308
}
309
)
310
311
submit_button = pn.widgets.Button(name="Submit", button_type="primary")
312
313
def handle_submit(event):
314
if validator.is_valid():
315
pn.state.notifications.success("Form submitted successfully!")
316
else:
317
pn.state.notifications.error("Please fix validation errors")
318
319
submit_button.on_click(handle_submit)
320
321
form = pn.Column(form_ui, submit_button)
322
```
323
324
### Integration with External APIs
325
326
```python
327
class APIClient(param.Parameterized):
328
329
api_key = param.String(default="")
330
endpoint = param.Selector(default='users', objects=['users', 'posts', 'comments'])
331
limit = param.Integer(default=10, bounds=(1, 100))
332
333
@param.depends('api_key', 'endpoint', 'limit')
334
def fetch_data(self):
335
"""Reactive method to fetch data from API"""
336
if not self.api_key:
337
return pn.pane.HTML("<p>Please provide API key</p>")
338
339
try:
340
# Simulate API call
341
url = f"https://api.example.com/{self.endpoint}"
342
params = {'limit': self.limit, 'key': self.api_key}
343
# response = requests.get(url, params=params)
344
# data = response.json()
345
346
# Mock data for demonstration
347
data = [{'id': i, 'name': f'Item {i}'} for i in range(self.limit)]
348
349
return pn.pane.JSON(data, depth=2)
350
351
except Exception as e:
352
return pn.pane.HTML(f"<p>Error: {str(e)}</p>")
353
354
api_client = APIClient()
355
356
# Create API client interface
357
api_interface = pn.Column(
358
"# API Data Viewer",
359
pn.Param(api_client, parameters=['api_key', 'endpoint', 'limit']),
360
pn.Divider(),
361
api_client.fetch_data
362
)
363
```
364
365
## Parameter Types and Widgets
366
367
Panel automatically maps parameter types to appropriate widgets:
368
369
- `param.String` → `TextInput`
370
- `param.Integer` → `IntInput` or `IntSlider` (with bounds)
371
- `param.Number` → `FloatInput` or `FloatSlider` (with bounds)
372
- `param.Boolean` → `Checkbox`
373
- `param.Selector` → `Select`
374
- `param.ListSelector` → `MultiSelect`
375
- `param.Date` → `DatePicker`
376
- `param.DateTime` → `DatetimePicker`
377
- `param.Range` → `RangeSlider`
378
- `param.Color` → `ColorPicker`
379
380
Custom widget mappings can override these defaults for specialized interfaces.