繁体   English   中英

散景圆不适合正方形?

[英]Bokeh Circle does not fit into square?

我正在使用散景绘制一些几何图形并遇到了这个问题。 我正在绘制一个边相等的矩形(即正方形),并在该正方形中绘制一个直径 = 正方形宽度的圆。 圆应该在边缘与正方形相切,但事实并非如此。

这是代码:

from bokeh.plotting import output_notebook, figure, show
output_notebook()

p = figure(width=500, height=500)

p.rect(0, 0, 300, 300, line_color='black')
p.circle(x=0, y=0, radius=150, line_color='black', 
         fill_color='grey',  radius_units='data')

p.axis.minor_tick_out = 0

show(p)

结果如下:

在此处输入图片说明

有什么我做错了或者可以改变以使圆圈完全适合正方形吗?

提前致谢,兰德尔

这是另一种情况 - 只是画一个圆圈:

p = figure(width=500, height=500, x_range=(-150, 150), y_range=(-150, 150))
p.circle(x=0, y=0, radius=150, line_color='black', 
         fill_color='grey', radius_units='data')
show(p)

圆的半径在 x 方向上是 150,但在 y 方向上不是。

在此处输入图片说明

我想报告,从 Bokeh 0.12.7 开始,这个问题现在可以以更简单的方式解决。

如其他帖子所述,主要问题不是圆不是圆,而是正方形不是正方形。 这是因为在默认情况下,Bokeh 绘制图形(画布)的实际区域通常不是正方形,甚至在宽度和高度设置为相同值时也是如此。 默认情况下,散景将尝试通过使用画布上的所有空间来绘制图形。 这会导致绘图的数据距离和像素距离之间不匹配。

从 0.12.7 开始,数字现在可以接受match_aspect属性,当设置为 True 时,会将数据空间的方面与绘图的像素空间相匹配。

在您的示例中,只需在图中添加match_aspect = True

p = figure(width=500, height=500, match_aspect=True, 
           title="Circle touches all 4 sides of square")
p.rect(0, 0, 300, 300, line_color='black')
p.circle(x=0, y=0, radius=150, line_color='black', 
         fill_color='grey',  radius_units='data')

现在将生产

圆接触正方形的所有 4 边

更新:请注意下面@DuCorey 的新答案。 从 Bokeh 0.12.7 开始,对于这种情况,现在可以使用方面控制。


问题实际上是正方形不是正方形,那是因为像素纵横比和“数据”纵横比不匹配。 即,每个像素的距离在 x 方向上与在 y 方向上不同。

有几个选项:

  • 您可以使用各种属性来控制中央绘图区域的尺寸(例如绘图边框宽度和轴刻度标签方向) 您还可以明确地控制您的数据范围。 换句话说,您可以使纵横比匹配,然后圆形和矩形将匹配

  • 您可以使用绝对像素单位(例如圆形的size ,并使用大square标记代替rect )而不是“数据”单位。

或者,如果您想要一个在方面不匹配时“变形”的圆,那么您最好的选择是使用具有相同widthheightellipse ,这将起作用,因为在这种情况下,散景有两个维度可用于测量(而不是单个radius ),并且可以独立地将每个radius与每个维度的比例匹配。

(这实际上是解释行为的根本区别: rect有两个维度可以独立测量circle没有,它只有一个,并且必须任意使用 x 或 y 维度来测量每个像素的距离)

好的,根据建议,我尝试了一些方法。

  • 更改了 y 轴刻度标签的方向 - 仍然存在问题。
  • 更改了各种对峙,甚至在绘图内的刻度标签中移动(具有负偏移)。 也没有用。
  • 将 figure() 中的 x_range 和 r_range 更改为相等的元组。 也没有用
  • 更改 plot_height(减小它),我最终可以通过真实和错误使圆适合具有 < 绘图宽度的 plot_height 的正方形。

许多伟大的实践控制情节的属性。 时间会投入。

但是,我尝试的最后一次更改效果最好。 这是第一个建议 - 更改情节边界。

奇怪的是,设置p.min_border=40 ,它在 0.12.6 上是默认值,瞧,它出现了图表的图表纵横比,其中 plot_width=plot_height 在屏幕上也确实是 1。

p = figure(plot_width=500, plot_height=500)

p.rect(0, 0, 300, 300, line_color=None)

p.circle(x=0, y=0, radius=150, line_color=None, 
         fill_color='lightgrey',  radius_units='data')

p.min_border=40

show(p)

显示添加p.min_border=40效果的前后图像。 任何超过 ~33 的值似乎都足以迫使绘图区域具有相同的屏幕 x 和 y 尺寸 - 所以正方形实际上是一个正方形(并且圆形适合内部)。

在此处输入图片说明

在此处输入图片说明

不确定,但蓝色矩形不是您的矩形。

代替:

p.rect(0, 0, 300, 300, line_color='black')

经过:

p.rect(-150, -150, 150, 150, line_color='black')

这样做的原因是您正在创建一个圆形标记(或圆形字形)并将其放置在位置 (0, 0),而您似乎想要创建一个以 0 为中心的圆形。

我认为这里的rect “碰巧”起作用,因为它可以在两个维度上正确缩放并保持“矩形”。

Keyword Args:
    radius (UnitsSpecPropertyDescriptor) : The radius values for circle markers (in "data space" units, by default). (default None)
    radius_dimension (BasicPropertyDescriptor) : What dimension to measure circle radii along. (default 'x')
    radius_units (Enum('screen', 'data')) :  (default 'data')

我想我的观点是在这里您通过尝试使用“字形”作为绘图并将单位指定为数据单位来采取捷径。

如果您想创建一个实际的圆圈,您可以执行以下操作:

th = np.linspace(0, 2*np.pi)

r = 150

p = figure(width=500, height=500)

p.rect(0, 0, 300, 300, line_color='black')

p.line(r * np.cos(th), r * np.sin(th), line_color='black')
# p.circle(x=0, y=0, radius=150, line_color='black',
#         fill_color='grey', radius_units='data')

p.axis.minor_tick_out = 0

show(p)

请注意,上面很难填充(我没有打扰),因为我猜你需要定义一些闭合多边形函数,而我只定义了一条恰好是闭合多边形的线,在这种情况下是一个圆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM