Так что здесь есть длинный ответ и короткий ответ.Давайте начнем с короткого ответа, который заключается в том, что нет необходимости создавать пользовательский виджет выбора для переменной данных, поскольку hvPlot позволяет автоматически выбирать между несколькими переменными данных, поэтому, если вы измените его на следующее:
rasterized_mesh = ds[time_vars].hvplot.quadmesh(
x='x', y='y', z=time_vars[::-1], crs=crs, width=600, height=400,
groupby=list(ds[var].dims[:-2]), rasterize=True, cmap='jet')
Вы получите DynamicMap, который позволяет выбирать непространственные измерения и переменную данных, и теперь вы можете встраивать их в свою панель, не требуя дополнительной работы.Если это все, что вас волнует , остановитесь здесь , так как мы собираемся войти в некоторые из внутренних органов, чтобы, как мы надеемся, обеспечить лучшее понимание.
Допустим, в течение минуты hvPlot не позволял выбиратьмежду переменными данных, что мы будем делать тогда?Итак, главное, что вам нужно знать, это то, что HoloViews позволяет создавать цепочки DynamicMaps, но не позволяет их вкладывать.Это может быть немного сложно обернуть голову, но мы разберем проблему на несколько этапов, а затем посмотрим, как мы можем достичь того, чего хотим.Так что же представляет собой цепочка событий, которая дала бы нам наш график?
- Выберите переменную данных
- Примените групповую обработку над непространственными измерениями
- Применить растеризациюк каждому QuadMesh
Как вы знаете, hvPlot заботится о шагах 2. и 3. для нас, так как мы можем внедрить шаг 1. до 2. и 3. В будущем мы планируем добавить поддержкудля передачи виджетов панели непосредственно в hvPlot, что означает, что вы сможете сделать все это за один шаг.Поскольку панель все еще является очень новым проектом, я покажу, как наши API в конечном итоге сделают этот процесс тривиальным, но сейчас нам придется придерживаться относительно многословного обходного пути.В этом случае мы должны изменить порядок операций:
- Применить групповую обработку по непространственным измерениям
- Выбрать переменную данных
- Применить растеризацию к каждомуQuadMesh
Для начала мы выбираем все переменные данных и пропускаем растеризацию:
meshes = ds[time_vars].hvplot.quadmesh(
x='x', y='y', z=time_vars, crs=crs, width=600, height=400,
groupby=list(ds[var].dims[:-2]))
Теперь, когда у нас есть DynamicMap, который содержит все данныемы могли бы хотеть показать, что мы можем применить следующие операции.Здесь мы воспользуемся утилитой hv.util.Dynamic
, которую можно использовать для цепочки операций над DynamicMap при вводе потоковых значений.В частности, на этом шаге мы создаем поток из виджета var_select
, который будет использоваться для переиндексации QuadMesh
внутри наших сеток DynamicMap
:
def select_var(obj, var):
return obj.clone(vdims=[var])
var_stream = Params(var_select, ['value'], rename={'value': 'var'})
var_mesh = hv.util.Dynamic(meshes, operation=select_var, streams=[var_select])
# Note starting in hv 1.12 you'll be able to replace this with
# var_mesh = meshes.map(select_var, streams=[var_select])
# And once param 2.0 is out we intend to support
# var_mesh = meshes.map(select_var, var=var_select.param.value)
Теперь у нас есть DynamicMap, который реагирует на измененияв виджете, но еще не растеризовали его, поэтому мы можем применить операцию rasterize
вручную:
rasterized_mesh = rasterize(var_mesh).opts(cmap='jet', width=600, height=400)
Теперь у нас есть DynamicMap, который связан с виджетом Selection, применяет групповую передачу и растеризуется, чтоТеперь мы можем встроить в панель.Другой подход, на который ссылается @jbednar выше, состоит в том, чтобы сделать все это за один шаг, сделав вызов hvPlot не динамическим и сделав выбор уровня времени и высоты вручную.Я не буду подробно останавливаться на этом, но это также правильный (хотя и менее эффективный) подход.
Как я уже говорил выше, в конечном итоге мы также намереваемся сделать все параметры hvPlot динамическими,это означает, что вы сможете сделать что-то подобное, чтобы связать значение виджета с аргументом ключевого слова hvPlot:
ds[time_vars].hvplot.quadmesh(
x='x', y='y', z=var_select.param.value, rasterize=True, crs=crs,
width=600, height=400, groupby=list(ds[var].dims[:-2]), cmap='jet')