如何动态调整散景图大小
How to fit bokeh plot size dynamically
我的问题与昨天的问题非常相似:
Bokeh resize plot dynamically
但由于我觉得两者之间的解决方案可能有点不同,所以我想 post 我自己的。我还复制了整个代码,这样任何人都可以 copy/paste 和 运行 它。
在下面的代码中,我基本上希望第二个散景图在我单击标题时占据整个视口,并在下一次单击时 return 恢复到原始大小。
作为辅助信息,我从 github 借用了部分代码。 Bootstrap4 用于 css。用于动画的 TweenMax,当然绘图库是 Bokeh。包含 bootstrap 的卡片大小按预期更改,但情节没有。如果我调整浏览器的大小,绘图会以某种方式自行调整大小。
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
。
我的问题与昨天的问题非常相似: Bokeh resize plot dynamically
但由于我觉得两者之间的解决方案可能有点不同,所以我想 post 我自己的。我还复制了整个代码,这样任何人都可以 copy/paste 和 运行 它。
在下面的代码中,我基本上希望第二个散景图在我单击标题时占据整个视口,并在下一次单击时 return 恢复到原始大小。
作为辅助信息,我从 github 借用了部分代码。 Bootstrap4 用于 css。用于动画的 TweenMax,当然绘图库是 Bokeh。包含 bootstrap 的卡片大小按预期更改,但情节没有。如果我调整浏览器的大小,绘图会以某种方式自行调整大小。
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
。