2014-10-31 64 views
7

散景剧情具有相等轴

我创建与PythonBokeh(见代码)的曲线图。散景剧情具有相等轴

from bokeh.plotting import * 

figure() 
hold() 
rect([1,3], [1,1], [1,0.5], [1,0.5]) 
patch([0,0,4,4], [2,0,0,2], line_color="black", fill_color=None) 
show() 

如何可以代表正方形(矩形具有相同的宽度和高度)以相等的轴为与命令axis('equal') matplotlib?

http://matplotlib.org/examples/pylab_examples/axis_equal_demo.html

我看到改变的情节的宽度和高度或定义轴范围来解决这个问题,但我认为,应该有一个更聪明的替代选项。

注意:我正在使用Python v.2.7.8Bokeh v.0.6.1

+0

这是一个悬而未决的问题:https://github.com/bokeh/bokeh/issues/474 – bigreddot 2014-11-04 17:11:06

+0

感谢您的链接。我期待着使用一个解决方案。 – Spirou 2014-11-07 12:13:53

+1

请注意@DuCorey关于'match_aspect'的0.12.7 – bigreddot 2017-08-30 14:52:56

回答

2

不幸的是,似乎两年后这个功能仍然缺失。作为一种解决方法,我已经编写了一个函数,可以适当地设置图的x_rangey_range属性,以显示具有给定高宽比的数据。只要您不允许使用框缩放等让用户修改纵横比的工具,此工作正常。

__all__ = ['set_aspect'] 

from bokeh.models import Range1d 

def set_aspect(fig, x, y, aspect=1, margin=0.1): 
    """Set the plot ranges to achieve a given aspect ratio. 

    Args: 
     fig (bokeh Figure): The figure object to modify. 
     x (iterable): The x-coordinates of the displayed data. 
     y (iterable): The y-coordinates of the displayed data. 
     aspect (float, optional): The desired aspect ratio. Defaults to 1. 
     Values larger than 1 mean the plot is squeezed horizontally. 
     margin (float, optional): The margin to add for glyphs (as a fraction 
     of the total plot range). Defaults to 0.1 
    """ 
    xmin = min(xi for xi in x) 
    xmax = max(xi for xi in x) 
    ymin = min(yi for yi in y) 
    ymax = max(yi for yi in y) 
    width = (xmax - xmin)*(1+2*margin) 
    if width <= 0: 
     width = 1.0 
    height = (ymax - ymin)*(1+2*margin) 
    if height <= 0: 
     height = 1.0 
    xcenter = 0.5*(xmax + xmin) 
    ycenter = 0.5*(ymax + ymin) 
    r = aspect*(fig.plot_width/fig.plot_height) 
    if width < r*height: 
     width = r*height 
    else: 
     height = width/r 
    fig.x_range = Range1d(xcenter-0.5*width, xcenter+0.5*width) 
    fig.y_range = Range1d(ycenter-0.5*height, ycenter+0.5*height) 

if __name__ == '__main__': 
    from bokeh.plotting import figure, output_file, show 

    x = [-1, +1, +1, -1] 
    y = [-1, -1, +1, +1] 
    output_file("bokeh_aspect.html") 
    p = figure(plot_width=400, plot_height=300, tools='pan,wheel_zoom', 
       title="Aspect Demo") 
    set_aspect(p, x, y, aspect=2) 
    p.circle(x, y, size=10) 
    show(p) 
+0

的新答案现在可以将FYI框缩放(从'0.12'开发版本开始)配置为尊重剧情的现有方面。 – bigreddot 2016-04-26 19:04:31

+0

关于时间框架,对于生成静态图像的库,方面控制将是一个微不足道的功能。不幸的是,Bokeh在更大的浏览器布局环境中嵌入了图表,并试图将固定方面与“网络响应”(也是一个连续请求的功能)进行协调,这成为一个非常棘手的问题。我们正在尽力而为,尽我们有限的资源许可。 – bigreddot 2016-04-26 19:07:37

+0

这个解决方案非常棒。然而,当它在0.12.5服务器上运行时,我不得不直接修改范围的开始和结束属性以使其工作。 'fig.x_range.start = xcenter - 0.5 * width fig.x_range.end = xcenter + 0.5 * width fig.y_range.start = ycenter - 0.5 * height fig.y_range.end = ycenter + 0.5 * height' – DuCorey 2017-07-06 21:49:54

5

从散景0.12.7开始,此功能已实施。情节现在可以接受两个新的属性。 match_aspect当设置为true时,它将将数据空间的方面与图的像素空间相匹配。例如,以数据单位绘制的正方形现在也是像素单位的完美正方形。

p = figure(match_aspect=True) 
p.circle([-1, +1, +1, -1], [-1, -1, +1, +1]) 

Bokeh match aspect = True

aspect_scale允许你通过对由match_aspect作出的方面校正的顶部指定乘数进一步控制纵横比。

p = figure(aspect_scale=2) 
p.circle([-1, +1, +1, -1], [-1, -1, +1, +1]) 

Bokeh aspect scale = 2

p = figure(aspect_scale=0.5) 
p.circle([-1, +1, +1, -1], [-1, -1, +1, +1]) 

Bokeh aspect scale = 0.5

+0

如果添加用于生成这些数字的代码,这将是有益的。 – jorgeh 2017-10-17 06:24:14

+1

@jorgeh感谢您的评论。我添加了用于生成数字的代码。 – DuCorey 2017-10-19 14:21:45