Python matplotlib图圆形日循环图(日极坐标图)

Python matplotlib图圆形日循环图(日极坐标图),python,python-3.x,pandas,matplotlib,Python,Python 3.x,Pandas,Matplotlib,我试图以玫瑰图/极坐标图的形式绘制采样策略的每日周期 我想展示我们的每个实验样本,其中距离中心的距离是一天,从0开始的角度表示采集样本的时间。理想情况下,我希望能够通过不同的变量给点上色 理想的绘图应如下所示: 模拟虚拟数据来解释问题 我有xarray格式的数据。我们有一个launchtime维度,它包含采集样本的时间,我们想用它来绘制一天中的时间,然后依次绘制每一天 将xarray作为xr导入 将numpy作为np导入 将matplotlib.pyplot作为plt导入 作为pd进口熊猫

我试图以玫瑰图/极坐标图的形式绘制采样策略的每日周期

我想展示我们的每个实验样本,其中距离中心的距离是一天,从0开始的角度表示采集样本的时间。理想情况下,我希望能够通过不同的变量给点上色

理想的绘图应如下所示:

模拟虚拟数据来解释问题 我有
xarray
格式的数据。我们有一个
launchtime
维度,它包含采集样本的时间,我们想用它来绘制一天中的时间,然后依次绘制每一天

将xarray作为xr导入
将numpy作为np导入
将matplotlib.pyplot作为plt导入
作为pd进口熊猫
从pandas.tseries.offset导入日期offset
将matplotlib.dates导入为mdates
进口itertools
值=np.随机.正常(大小=100)
预期时间=局部放电日期范围(“2000-01-01”,freq=“180分钟”,周期=100)
#添加随机偏移以模拟+/-真实预期释放时间
np.abs(np.random.normal(0,10,size=100))中i的时间增量=np.array([DateOffset(分钟=max(0,min(int(i),59)))
时间=[预期时间[i]+时间增量[i]如果(i%2==0)其他预期时间[i]-范围(100)内i的时间增量[i]
df=pd.DataFrame({“launchtime”:time,“value”:value})
ds=df.set_index(“launchtime”)。为_xarray()
ds=ds.assign_coords(预期_时间=(“启动时间”,预期_时间))
我到目前为止的想法
def time_到_角度(dt:pd.Timestamp)->浮点:
第二天=86天
开始日期=pd.to_日期时间(f“{dt.day}-{dt.month}-{dt.year}”)
delta=(dt-开始日)
n_秒=增量秒
#返回角(度)
返回(n秒/秒/天)*360
#0度角
角度=[ds.launchtime.values中dt的时间到角度(pd.to_日期时间(dt))]
#半径有多远
days=np.arange(np.unique(ds[“launchtime.day”].values).size)
#如何在极坐标系中绘图?我必须画一个x,y网格并绘制成散点图吗?

任何关于如何着手解决这个问题的建议都将不胜感激

通过一点高中三角法,它可以非常简单地作为一个散点图来实现

  • 将一天中的时间视为以弧度计算的角度
  • 以一天(多大)为半径
  • 然后简化为简单使用sin()cos()来计算xy坐标
  • 为了更好的测量,我们也决定给点上色。。。时钟表面显示24小时,模拟时钟只显示12小时,这并不令人满意

我们可以将
projection=“polar”
参数用于
ax=plt.subplot(projection='polar')
参数,以便创建具有以下内容的绘图:

  • 显示一天中时间的角度(
    theta
    ,以弧度定义)
  • 半径显示自第一个样本(
    r
    )起的天数
我们需要对一天中的时间数据和

来自sklearn.preprocessing导入标签编码器
定义时间到角度(dt:pd.时间戳)->浮点:
第二天=86天
开始日期=pd.to_日期时间(f“{dt.day}-{dt.month}-{dt.year}”)
delta=(dt-开始日)
n_秒=增量秒
#以弧度为单位的返回角
返回(n秒/秒/天)*2*np.pi
#0度角
角度=[ds.launchtime.values中dt的时间到角度(pd.to_日期时间(dt))]
#沿半径的距离=天数
le=标签编码()
days=le.fit_转换(ds[“launchtime.dayofyear”].值)
#使用matplotlib中的极轴投影图
ax=plt.子地块(投影='polar')
ax.设置θ方向(-1)
ax.设置θ0位置(“N”)
最大散布(角度、天数、标记=“o”)
ax.set_xticklabel(['00:00','03:00','06:00','09:00','12:00','15:00','18:00','21:00',]))
ax.设置标签([])
ax.设置标题(“采样计划[UTC]”)
plt.show()
输出如下所示:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import math

fig, ax = plt.subplots(1,1, figsize=(4, 4))

df = pd.DataFrame({"sampledate":pd.date_range("01-apr-2021", "09-apr-2021 23:59", freq="30s")})
# drop a bit of data so it's not perfect circles...
df = df.loc[np.random.choice(df.index, int(len(df)/200) )]

df["angle"] = ((df["sampledate"] - df["sampledate"].dt.floor("D")).dt.total_seconds() / (24*60*60)) * 2*math.pi
df["radius"] = (df["sampledate"] - df["sampledate"].min()).dt.days+1


# scatter, radius is how old sample is, angle is time of day
ax.scatter(x=df["angle"].apply(math.sin) * df["radius"], y=df["angle"].apply(math.cos) * df["radius"], 
           c=np.where(df.sampledate.dt.hour.le(12), "red", "pink"), s=10)
ax.axis("off")

# draw markers on clock face...
for h in list(range(0, 24, 3)):
    a = (h/24)*2*math.pi
    x = math.sin(a)*df["radius"].max()
    y = math.cos(a)*df["radius"].max()
    ax.annotate(h, xy=(x, y), xytext=(x*1.1,y*1.1), backgroundcolor="yellow")