如何使用datashader将数据框中多组极坐标数据按分组绘制为折线图
问题原因
你的代码存在3个影响结果的问题:
- 提前在坐标转换前就对数据做了分组,分组后的子数据框没有后续生成的
x、y字段,绘图时缺少必要字段 - 循环内每次生成的折线聚合结果都会覆盖之前的结果,所有分组的折线没有叠加到同一张画布上,最后只会显示最后一个分组的折线
- 无需手动循环分组,datashader的
line()方法原生支持按指定字段分组绘制独立折线
修正方案
方案1:直接使用内置分组参数(推荐)
调用cvs.line()时指定by='Name'参数,datashader会自动按名称字段分组,每组生成独立折线,代码更简洁效率也更高:
import datashader as ds import pandas as pd import colorcet import numpy as np import matplotlib.pyplot as plt # 读取数据 df = pd.read_csv('file.csv') df['Date'] = pd.to_datetime(df['Date']) # 极坐标转笛卡尔坐标 df['starlink_alt'] = 90 - df['starlink_alt'] df['x'] = df.apply(lambda row: np.deg2rad(row.starlink_alt) * np.cos(np.deg2rad(row.starlink_az)), axis=1) df['y'] = df.apply(lambda row: -1 * np.deg2rad(row.starlink_alt) * np.sin(np.deg2rad(row.starlink_az)), axis=1) # 绘图:by参数指定分组字段 cvs = ds.Canvas(plot_width=2000, plot_height=2000) agg = cvs.line(df, 'y', 'x', by='Name') img = ds.tf.shade(agg, cmap=colorcet.fire, how='eq_hist') # 显示结果 plt.imshow(img.to_pil()) plt.axis('off') plt.show()
方案2:手动循环叠加
如果需要自定义每组的样式、必须手动循环实现,可以每次把分组的聚合结果累加到同一个聚合对象中:
import datashader as ds import pandas as pd import colorcet import numpy as np import matplotlib.pyplot as plt # 读取数据+坐标转换 同方案1 df = pd.read_csv('file.csv') df['Date'] = pd.to_datetime(df['Date']) df['starlink_alt'] = 90 - df['starlink_alt'] df['x'] = df.apply(lambda row: np.deg2rad(row.starlink_alt) * np.cos(np.deg2rad(row.starlink_az)), axis=1) df['y'] = df.apply(lambda row: -1 * np.deg2rad(row.starlink_alt) * np.sin(np.deg2rad(row.starlink_az)), axis=1) cvs = ds.Canvas(plot_width=2000, plot_height=2000) agg = None for name in df['Name'].unique(): group_df = df[df['Name'] == name] current_agg = cvs.line(group_df, 'y', 'x') agg = current_agg if agg is None else agg + current_agg img = ds.tf.shade(agg, cmap=colorcet.fire, how='eq_hist') plt.imshow(img.to_pil()) plt.axis('off') plt.show()
内容的提问来源于stack exchange,提问作者Taiko
相关产品推荐
相关产品推荐

