1

我正在使用 Plotly Express 生成 WindRose,并且想知道是否可以偏移径向线的起点。

我想要实现的是将 0-2 MPH 风显示为一个显示平静的圆圈,如图 2 所示。

不确定它是否可能或如何这样做,任何帮助将不胜感激。

使用 Plotly Express 生成的 WindRose

我想得到的风玫瑰

fig = px.bar_polar(df, r= "Frequency", theta="Direction",
                   color="Strength", template="none",
                   labels={"Strength": "Wind Speed in MPH"}
                   )

fig.update_layout(legend=dict(
    orientation="h",
    yanchor="top",
    y=-0.1,
    xanchor="center",
    x=0.5),
    polar=dict(radialaxis=dict(showticklabels=False, ticks='', linewidth=0)
    )
)
fig.show()

Direction,Strength,Frequency
N,0-2,1.45
N,2-5,0.4
N,5-7,
N,7-10,
N,10-15,
N,15-20,
NNE,0-2,0.53
NNE,2-5,0.53
NNE,5-7,
NNE,7-10,
NNE,10-15,
NNE,15-20,
NE,0-2,1.06
NE,2-5,
NE,5-7,
NE,7-10,
NE,10-15,
NE,15-20,
ENE,0-2,0.79
ENE,2-5,0.4
ENE,5-7,
ENE,7-10,
ENE,10-15,
ENE,15-20,
E,0-2,1.32
E,2-5,
E,5-7,
E,7-10,
E,10-15,
E,15-20,
ESE,0-2,1.19
ESE,2-5,0.26
ESE,5-7,
ESE,7-10,
ESE,10-15,
ESE,15-20,
SE,0-2,1.72
SE,2-5,1.19
SE,5-7,0.4
SE,7-10,0.13
SE,10-15,
SE,15-20,
SSE,0-2,1.19
SSE,2-5,3.04
SSE,5-7,1.98
SSE,7-10,0.4
SSE,10-15,
SSE,15-20,
S,0-2,1.06
S,2-5,3.17
S,5-7,1.19
S,7-10,
S,10-15,
S,15-20,
SSW,0-2,0.13
SSW,2-5,2.11
SSW,5-7,0.4
SSW,7-10,
SSW,10-15,
SSW,15-20,
SW,0-2,0.79
SW,2-5,0.92
SW,5-7,0.53
SW,7-10,
SW,10-15,
SW,15-20,
WSW,0-2,0.79
WSW,2-5,1.19
WSW,5-7,0.26
WSW,7-10,
WSW,10-15,
WSW,15-20,
W,0-2,0.92
W,2-5,3.83
W,5-7,2.64
W,7-10,0.4
W,10-15,
W,15-20,
WNW,0-2,3.3
WNW,2-5,7.53
WNW,5-7,9.64
WNW,7-10,4.62
WNW,10-15,0.79
WNW,15-20,
NW,0-2,1.72
NW,2-5,10.04
NW,5-7,11.1
NW,7-10,7.4
NW,10-15,1.06
NW,15-20,
NNW,0-2,1.85
NNW,2-5,1.85
NNW,5-7,0.79
NNW,7-10,
NNW,10-15,
NNW,15-20,

4

2 回答 2

1

通过在 update_layout 中使用“孔”,我找到了另一种在极坐标图中间添加圆圈的解决方案。代码附在下面:

fig2 = px.bar_polar(df, r="Frequency", theta="Direction",
                    color="Strength", template="none",
                    labels={"Strength": "Wind Speed <br>&nbsp;&nbsp;&nbsp; in MPH:"
                            }
                    )

fig2.add_annotation(
    text="Calm<br>" + " " + percent + "%", x=0.5, y=0.5, showarrow=False
)

fig2.add_annotation(
    text="Calm Values are for <br> Wind Speed <2.0 MPH <br />", x=0.93, y=-0.13, showarrow=False
)

fig2.update_layout(legend=dict(
    orientation="h",
    yanchor="middle",  
    y=-0.1,
    xanchor="center",
    x=0.5,
    font=dict(
        size=14)),
    polar=dict(hole=0.1, radialaxis=dict(showticklabels=False, ticks='', linewidth=0)
               ),
    margin=dict(t=110),
    title=dict(
        text=title,
        xanchor='center',
        yanchor='top'
    )
)

输出:以圆圈为中心的风玫瑰

由于 0-2 MPH 在中间显示为一个圆圈,因此在我的数据框中,我将所有 0-2 MPH 的值设置为零,这样可以确保不显示 0-2 个 bin。

于 2020-09-16T21:48:51.687 回答
1

由于似乎没有办法bar_polar在 Plotly 中调整绘图的起始半径值,因此最好的办法是尝试找到一些解决方法。

诚然,这是一个非常hacky 的解决方案,但为了确保图表不会太靠近原点,我们可以创建一个New_Frequency列,简单地将任意值添加到该Frequency列。我选择了 30。请注意,这样做会扭曲条形之间的相对距离(如果这是一个问题,则需要以某种方式修改解决方案)。

然后我们将rbar_polar 方法中的参数设置为这个新列,并修改悬停数据,使其显示原始的频率列。

在此处输入图像描述

现在我们可以绘制一个带有文本“Calm”的圆圈,该圆圈覆盖对应于 的值的内部条0-2 MPH。添加形状时,您需要指定笛卡尔坐标,尽管这是一个极坐标图。经过反复试验,似乎 x=0.5, y=0.5 是 bar_polar 图的中心,从 x0=0.4, y0=0.4, x1=0.6, y1=0.6 开始的圆圈覆盖了内部条形图。我不知道是否有这方面的文档。

如果您只追求图像,那么希望它看起来不错。请注意,在图例中切换不同的风速会扭曲情节,并且圆圈将不再覆盖内部条,因此您会失去一些情节的互动性。

在此处输入图像描述

我已包含以下代码:

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

df = pd.read_csv("windrose.csv")

## this adds 30 to all frequencies, so 0-2 becomes 30-32
df["New_Frequency"] = df["Frequency"] + 30

fig = px.bar_polar(df, r="New_Frequency", theta="Direction",
                   color="Strength", template="none",
                   labels={"Strength": "Wind Speed in MPH"},
                   hover_data={"Strength":True, "New_Frequency":False, "Frequency":True ,"Direction":True}
                   )

fig.add_shape(
    type="circle",
            xref="paper",
            yref="paper",
            x0=0.4,
            y0=0.4,
            x1=0.6,
            y1=0.6,
            line_color="Black",
            fillcolor="White",
            # text="Calm"
)

fig.add_annotation( # add a text callout with arrow
    text="Calm", x=0.5, y=0.5, showarrow=False
)

fig.update_layout(width=800, height=800)
fig.update_layout(legend=dict(
    orientation="h",
    yanchor="top",
    y=-0.1,
    xanchor="center",
    x=0.5),
    polar=dict(radialaxis=dict(showticklabels=False, ticks='', linewidth=0)
    )
)
fig.show()
于 2020-09-04T04:46:52.073 回答