Bokeh График с равни оси

Bokeh График с равни оси

Създадох Plot с Python библиотека Bokeh (вижте кода).

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()

Как мога да представя квадратите (правоъгълник с еднаква ширина и височина) с еднакви оси като в matplotlib с командата axis('equal')?

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

Виждам опцията за промяна на ширината и височината на графиката или дефиниране на обхвата на осите за решаване на този проблем, но мисля, че трябва да има по-интелигентна алтернатива.

ЗАБЕЛЕЖКА: Използвам Python v.2.7.8 и Bokeh v.0.6.1.


person Spirou    schedule 31.10.2014    source източник
comment
Това е открит проблем: github.com/bokeh/bokeh/issues/474   -  person bigreddot    schedule 04.11.2014
comment
Благодаря за линка. Очаквам с нетърпение да използвам решение.   -  person Spirou    schedule 07.11.2014
comment
Моля, обърнете внимание на новия отговор от @DuCorey по-долу относно match_aspect в 0.12.7   -  person bigreddot    schedule 30.08.2017


Отговори (2)


От Bokeh 0.12.7 тази функция е внедрена. Парцелите вече могат да приемат два нови имота. match_aspect, което, когато е зададено на true, ще съответства на аспекта на пространството от данни на пикселното пространство на графиката. Например, квадратите, начертани в единици данни, вече ще бъдат идеални квадрати и в пикселни единици.

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

„Аспект

aspect_scale ви позволява допълнително да контролирате съотношението на страните, като посочите множител върху корекцията на страните, направена от match_aspect.

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

„Скала

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

„Скала

person DuCorey    schedule 30.08.2017
comment
Би било поучително, ако добавите кода, използван за генериране на тези цифри. - person jorgeh; 17.10.2017
comment
@jorgeh Благодаря за коментара. Добавих кода, който беше използван за генериране на фигурите. - person DuCorey; 19.10.2017

За съжаление изглежда, че две години по-късно тази функция все още липсва. Като заобиколно решение, написах функция, която задава свойствата x_range и y_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)
person Martin Wiebusch    schedule 23.04.2016
comment
За ваша информация увеличението на кутията вече може (от 0.12 компилации за разработчици) да бъде конфигурирано така, че да зачита съществуващия аспект на сюжета. - person bigreddot; 26.04.2016
comment
По отношение на времевата рамка, за библиотека, която генерира статични изображения, контролът на аспектите би бил тривиална функция. За съжаление, Bokeh вгражда графики в по-голям контекст на оформлението на браузъра и опитът да се съчетае фиксиран аспект с уеб реакцията (също непрекъснато изисквана функция), се превръща в много труден проблем. Ние работим върху това възможно най-добре и толкова бързо, колкото ни позволяват ограничените ресурси. - person bigreddot; 26.04.2016
comment
Това решение е страхотно. Въпреки това, когато го внедрявах, за да работи на сървър 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 - person DuCorey; 07.07.2017
comment
Моля, обърнете внимание на новия отговор от @DuCorey по-долу за match_aspect в 0.12.7 - person bigreddot; 30.08.2017