我正在使用散景绘制一些几何图形并遇到了这个问题。我正在绘制一个具有相等边(即正方形)的矩形,并在该正方形中绘制一个直径=正方形宽度的圆。圆圈应与边缘处的正方形相切,但不是。
这是代码:
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方向上。
答案 0 :(得分:4)
更新:请注意以下@DuCorey的新答案。从Bokeh 0.12.7开始,对于这种情况,方位控制现在可用。
问题实际上是正方形不是正方形,这是因为像素长宽比和“数据”宽高比不匹配。即,每个像素的距离在x方向上不同于在y方向上的距离。
有几个选择:
您可以使用各种属性来控制中心绘图区域的尺寸(例如,绘图边框宽度和轴刻度标签方向)您还可以显式控制数据范围。换句话说,您可以制作宽高比匹配,然后圆圈和矩形将匹配
您可以使用绝对像素单位(例如size
表示圆圈,并使用较大的square
标记代替rect
)而不是“数据”单位。
或者,如果你想要一个在方面不匹配时“变形”的圆圈,那么你最好的办法就是使用ellipse
和width
相同的height
将起作用,因为在这种情况下,散景有两个尺寸用于测量(而不是单个radius
)并且可以独立地匹配每个尺寸的尺度。
(这实际上是解释行为的根本区别:rect
有两个维度可以独立衡量。circle
不,它只有一个,并且必须任意使用x或y维度来测量每个像素的距离)
答案 1 :(得分:3)
我想报告一下,截至Bokeh 0.12.7,现在可以更简单的方式修复此问题。
如其他帖子所述,主要问题不是圆圈不是圆形,而是方形不是正方形。这是因为Bokeh绘制图形(画布)的实际区域默认情况下通常不是正方形,或者甚至在宽度和高度设置为相同值时也是如此。默认情况下,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')
现在将生成
答案 2 :(得分:0)
不确定,但是bleu矩形不是你的矩形。
替换:
p.rect(0, 0, 300, 300, line_color='black')
人:
p.rect(-150, -150, 150, 150, line_color='black')
答案 3 :(得分:0)
好的,基于这些建议,我尝试了一些方法。
控制情节属性的很多很棒的练习。时间会投入。
然而,我尝试过的最后一次改变效果最好。这是最初的建议之一 - 改变情节边界。
奇怪的是,设置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尺寸 - 因此正方形实际上是正方形(并且圆形适合内部)。
答案 4 :(得分:0)
原因是你正在创建一个圆形标记(或圆形字形)并将其放在位置(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)
注意上面的内容更难填充(我没有打扰),因为我猜你需要定义一些闭合的多边形函数,而我只定义了一个恰好是闭合多边形的线,在本例中是一个圆。