Я озадачен тем, как использовать стили HoloViews для настройки графиков и достижения согласованного внешнего вида в бэкэндах.HoloViews объявляется как пакет, который обеспечивает уровень абстракции для нескольких бэкэндов, в частности, Bokeh и Matplotlib, но я полностью терплю неудачу в моих попытках получить графики, сгенерированные с использованием этих бэкэндов, чтобы они выглядели одинаково.Настройки в одном бэкэнде игнорируются другим, и у каждого бэкэнда пропущено множество (большинство) опций форматирования, поэтому необходимо прорваться через абстракцию для вызовов более низкого уровня непосредственно бэкэндам.
Я подозреваю, что я 'Я просто что-то упустил или не смог найти соответствующую документацию.
Например, приведенный ниже код (с использованием настроек, которые не пытаются создать такой же внешний вид, но раскрывают некоторые проблемы) приводит к результатам Matplotlib (правильно), что
- игнорировать попытку достижения равномерного внешнего вида для точечного цвета точечной диаграммы,
- игнорировать попытку переопределить цвет полос гистограммы,
- маргинальные гистограммы с метками осей, которые явно удалены в версиях Bokeh (слева),
- имеют маргинальные гистограммы, которые не имеют рамок и не имеют вертикальной оси, присутствующей в версии Bokeh,
- не имеют контроляили настройки стиля осей, и
- имеют дополнениеНа графике Боке отсутствуют метки всех вспомогательных участков.
Кроме того, существует множество дополнительных настроек для обоих графиков бэкэнда (например, линий сетки, цвета рамки), для которых я не могу найти настройки.
Как настроить стили в HoloViews для достижения полного и согласованного контроля над графиками, созданными Bokeh и Matplotlib?
import numpy as np
import pandas as pd
import holoviews as hv
hv.extension('bokeh', 'matplotlib')
ds = hv.Dataset({'x': np.random.randn(100), 'y1': np.random.randn(100), 'y2': np.random.randn(100), 'y3': np.random.randn(100)},
['x'],['y1', 'y2', 'y3'])
def mpl_style_hook(plot, element):
# Settings required here are neither complete, nor do they correspond directly to the backend's naming
# Where is the correspondence between handles and the backend's names documented?
pass
def bok_style_hook(plot, element):
# Such a small set of abstractions is provided, it is almost always necessary to resort to hooks
plot.state.title.align = "center"
plot.handles['xaxis'].axis_label_text_color = 'red'
plot.handles['yaxis'].axis_label_text_color = 'green'
plot.handles['xaxis'].axis_label_text_font_style = "normal"
plot.handles['yaxis'].axis_label_text_font_style = "normal"
# Attempt to set options that apply to both backends; but ignored by Matplotlib
hv.opts.defaults(hv.opts.Scatter(color='green'), hv.opts.Histogram(fill_color='yellow'))
# Explictily set backend to avoid warnings (`backend=` isn't sufficient)
hv.Store.current_backend = 'bokeh'
hv.opts.defaults(
hv.opts.Scatter(line_color='orange', size=6, fill_alpha=1.0, hooks=[bok_style_hook]),
hv.opts.Histogram(fill_color='cyan', fill_alpha=0.9, line_width=1, line_color='gray', hooks=[bok_style_hook]),
backend='bokeh')
hv.Store.current_backend = 'matplotlib'
hv.opts.defaults(
hv.opts.Scatter(hooks=[mpl_style_hook]),
# Histogram color ignored
hv.opts.Histogram(color='orange', hooks=[mpl_style_hook]),
backend='matplotlib')
hv.Store.current_backend = 'bokeh'
s1 = hv.Scatter(ds, 'x', 'y1').opts(hv.opts.Scatter(labelled=[None, 'y'])).hist(num_bins=51, dimension=['x','y1'])
s2 = hv.Scatter(ds, 'x', 'y2').opts(hv.opts.Scatter(labelled=[None, 'y'])).hist(num_bins=51, dimension='y2')
s3 = hv.Scatter(ds, 'x', 'y3').hist(num_bins=51, dimension='y3')
p = (s1 + s2 + s3).opts(hv.opts.Histogram(labelled=[None, None]), hv.opts.Layout(shared_axes=True)).cols(1)
hv.save(p, '_testHV.html', backend='bokeh')
hv.save(p, '_testHV.png', backend='matplotlib')
p