我的问题与昨天的问题非常相似: Bokeh resize plot dynamically
但由于我觉得两者之间的解决方案可能有点不同,所以我想发布自己的解决方案。我还复制了整个代码,以便任何人都可以复制/粘贴并运行它。
在下面的代码中,我基本上希望第二个 Bokeh 图在我单击标题时占据整个视口(viewport),并在下一次单击时返回到原始大小。
作为辅助信息,我从github上借用了部分代码。 Bootstrap4 用于 css。用于动画的 TweenMax,当然绘图库是 Bokeh。包含的引导卡大小按预期更改,但绘图没有。如果我调整浏览器的大小,绘图会以某种方式自行调整大小。
import pandas as pd
import numpy as np
import io
import random
from jinja2 import Template
from bokeh.embed import components
from bokeh.plotting import figure
from bokeh.resources import INLINE
from bokeh.util.browser import view
PLOT_OPTIONS = dict(plot_width=800, plot_height=300)
SCATTER_OPTIONS = dict(size=12, alpha=0.5)
data = lambda: [random.choice([i for i in range(100)]) for r in range(10)]
# red = figure(sizing_mode='scale_width', tools='pan', **PLOT_OPTIONS)
red = figure(sizing_mode='stretch_both', tools='pan')
red.scatter(data(), data(), color="red", **SCATTER_OPTIONS)
# blue = figure(sizing_mode='fixed', tools='pan', **PLOT_OPTIONS)
blue = figure(sizing_mode='stretch_both', tools='pan', id="blue_fig")
blue.scatter(data(), data(), color="blue", **SCATTER_OPTIONS)
green = figure(sizing_mode='scale_width', tools='pan', **PLOT_OPTIONS)
green.scatter(data(), data(), color="green", **SCATTER_OPTIONS)
########## RENDER PLOTS ################
# Define our html template for out plots
template = Template('''<!DOCTYPE html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.4/TweenMax.min.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
{{ js_resources }}
{{ css_resources }}
</head>
<body>
<div id="panel">
<div class="col-md-6" id="card1">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-sm-4">
<h4 class="card-title mb-0">plot 1</h4>
</div>
</div>
<div id="div1" style="height:400px;">
{{ div1 }}
</div>
</div>
</div>
</div>
<div class="col-md-6" id="card2">
<div class="card">
<div class="card-body" style="background:yellow; border:solid 1px red">
<div class="row">
<div class="col-sm-4">
<h4 class="card-title mb-0"><a href='#' id="plot2">plot 2</a></h4>
</div>
</div>
<div id="div2" style="height:400px;">
{{ div2 }}
</div>
</div>
</div>
</div>
</div>
<script>
(function($){
var i = 0;
var po = $('#panel').offset();
var co = $('#card2').offset();
var x=0, y=po.top-co.top;
$('#plot2').click(function(){
if(i==0){
TweenMax.to($("#card2"), 0.5, {x:x, y:y, className:"col-md-12"});
TweenMax.to($("#div2"), 0.5, {height:800});
i = 1;
} else {
TweenMax.to($("#card2"), 0.5, {x:0, y:0, className:"col-md-6"});
TweenMax.to($("#div2"), 0.5, {height:400});
i = 0;
}
$(window).resize();
$(window).trigger('resize');
});
})(jQuery);
</script>
</body>
</html>
''')
resources = INLINE
js_resources = resources.render_js()
css_resources = resources.render_css()
script, div = components(red)
div1 = div+script
script, div = components(blue)
div2 = div+script
html = template.render(js_resources=js_resources,
css_resources=css_resources,
div1=div1,
div2=div2)
filename = 'embed_multiple_responsive.html'
with io.open(filename, mode='w', encoding='utf-8') as f:
f.write(html)
view(filename)
最佳答案
这里是对你的代码的修改:
向 figure()
添加一个 id
参数:
blue = figure(sizing_mode='stretch_both', tools='pan', id="blue_fig")
添加onUpdate
事件并调用Bokeh.index["blue_fig"].resize()
:
TweenMax.to($("#div2"), 0.5, {height:800, onUpdate:function(){Bokeh.index["blue_fig"].resize();}});
TweenMax.to($("#div2"), 0.5, {height:400, onUpdate:function(){Bokeh.index["blue_fig"].resize();}});
如果图形很复杂,resize()
很慢,将onUpdate
改为onComplete
。
关于python - 如何动态调整 Bokeh 图大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48879674/