【问题标题】:How can I rotate the arrow marker in a Bokeh plot to show wind speed direction?如何旋转散景图中的箭头标记以显示风速方向?
【发布时间】:2022-01-19 16:57:23
【问题描述】:

我想做的是使用散点图来显示风速及其方向。我想使用三角形标记并使用旋转来指示风速。然而,由于散景默认三角形是等边三角形,风向实际上变得混乱(你无法分辨哪个是头部哪个是尾部)。

有什么方法可以改变/创建我自己的等腰三角形吗?这样我就可以分辨出三角形中哪个是头哪个是尾。

这是我所拥有的示例: Bokeh Scatter Plot with Rectangular Marker

为了清楚起见,这里是我正在寻找的形状标记的快速草图: Desired Rectangle vs Default Rectangle Marker

这是一个示例数据集。我还使用了 J'e 建议的箭头。这是一个示例结果:

这工作正常,但并不完美。因为我打算嵌入这个图并拉伸它(sizing_mode="stretch_both"),所以角度会看起来不一样。在使用矩形和角度进行绘制时,我认为这不是问题。

【问题讨论】:

  • 为了澄清,您想要一个带有多个三角形的图,每个三角形都“旋转”以指示给定经度/纬度的风向?在您的帖子中添加图片可能会有所帮助。
  • 是的,我可以轻松地创建带有标记的绘图并根据风向旋转每个绘图。但是,对于边长相等的三角形,很难区分三角形实际旋转的方式(参见添加到 cmets 的图片)
  • 如果你喜欢这个外观但又关心改变角度的拉伸,也许从限制的角度考虑问题会帮助你的 Delta X、Delta Y 值非常小。没有实际的调整大小会改变角度。 - 如果您对 VeeHead 感到满意,请不要忘记接受答案。这样做您还将获得声望点数。

标签: python bokeh scatter-plot marker


【解决方案1】:

API 中似乎没有任何东西可以直接执行此操作。使用bokeh.models VeeHead,可以绘制 VeeHead 箭头

import numpy as np
from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource
from bokeh.models import Arrow, VeeHead

# Create a sin wave of x/y coordinates 
N = 300
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=y))
TOOLS = "pan,wheel_zoom,box_zoom,reset,save"

# create a new plot and add a renderer
p = figure(tools=TOOLS, width=700, height=700, title=None)
p.line('x', 'y', source=source)


for i in range(N-1):
    p.add_layout(Arrow(end=VeeHead(size=25,fill_alpha=0.5), x_start=x[i], y_start=y[i], x_end=x[i+1], y_end=y[i+1])) 
show(p)

您不是像第一个示例中那样几乎没有尾巴,而是像本示例中那样添加一个。请注意,尾巴有它自己的风格,我在这个例子中没有设置。

import numpy as np
from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource
from bokeh.models import Arrow, VeeHead

# prepare some date
N = 300
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=y))
TOOLS = "pan,wheel_zoom,box_zoom,reset,save"

# create a new plot and add a renderer
p = figure(tools=TOOLS, width=700, height=700, title=None)
p.line('x', 'y', source=source)

for i in range(11, N-1):
    m = (y[i]-y[i-1])/(x[i]-x[i-1])
    Y = m*(x[i]-x[i-10]) # not point slope
    p.add_layout(Arrow(end=VeeHead(size=25,fill_alpha=0.5), x_start=x[i-10], y_start=Y, x_end=x[i], y_end=y[i])) 
show(p)

【讨论】:

  • 箭头的唯一问题是它们需要两个点才能被绘制(不是角度)。如果 x 轴和 y 轴具有相同的单位和相同的大小,则很容易完成。当 x 是基于时间的而 y 是 mph 时,情况会变得更加复杂。现在,如果有一种方法可以让我得到 x 轴的“长度”和“y 轴的长度”来计算比例,那么我可以使用它。
  • 您可以在原始问题中添加几行数据吗?我认为这仍然可以完成
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
相关资源
最近更新 更多