python - 如何动态调整 Bokeh 图大小

标签 python jquery css plot bokeh

我的问题与昨天的问题非常相似: 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/

相关文章:

python - 导入对日志记录的副作用 : how to reset the logging module?

jquery - Chrome 中的低调验证不会使用 dd/mm/yyyy 进行验证

jquery - 计算div标签内img标签的数量

css - 为什么位置 :absolute my footer is fixed in the middle of the page when I scroll it?

python - 没有PIP的依赖python模块的离线安装

python - 如何访问FormView中的request对象

类似 Jquery Finder 的菜单

html - 固定居中的粘性页脚无法定位在中心..请提供想法

html - 使用纯 CSS 创建形状

python - pyplot.show() 无法生成图表,导致 IDLE 重新启动