如何在Mathematica/Python中制作带时间分段颜色的通量直方图
用Python Matplotlib实现带时间分段颜色的通量直方图
嘿,我之前也碰到过类似的需求,用Mathematica的堆叠条形图确实容易卡壳,反而用Python的matplotlib能更灵活地搞定这个效果,给你分享个简便的实现思路和代码:
核心思路
- 整理数据:把每个通量值对应的所有时间点收集起来,统计每个通量的出现次数(也就是直方图条形的高度)。
- 拆分条形分段:对每个通量的条形,按出现次数拆分成N个高度为1的小分段,每个分段用对应的时间值映射到颜色条的颜色。
- 逐个绘制分段:用matplotlib的矩形元素逐个绘制这些小分段,精准控制每个分段的颜色。
代码示例
假设你的数据是CSV格式,两列分别是time(时间值)和flux(通量值):
import pandas as pd import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from matplotlib import cm from matplotlib.colors import Normalize # 1. 读取并整理数据 df = pd.read_csv('flux_data.csv') # 替换成你的数据文件路径 # 按通量值分组,收集每个通量对应的所有时间点 flux_groups = df.groupby('flux')['time'].apply(list).reset_index() # 计算每个通量的出现次数 flux_groups['count'] = flux_groups['time'].apply(len) # 2. 设置颜色映射:把时间值归一化到颜色条的范围 time_min = df['time'].min() time_max = df['time'].max() norm = Normalize(vmin=time_min, vmax=time_max) cmap = cm.viridis # 可以换成你喜欢的色条,比如plasma、coolwarm等 # 3. 绘制图形 fig, ax = plt.subplots(figsize=(10, 6)) bar_width = 0.8 # 条形宽度 x_positions = range(len(flux_groups)) # 每个通量的x位置 for i, row in enumerate(flux_groups.itertuples()): flux_val = row.flux times = row.time count = row.count x = x_positions[i] # 逐个绘制每个时间对应的小分段 for j in range(count): # 小分段的位置:x起始,y起始,宽度,高度 rect = Rectangle( (x - bar_width/2, j), bar_width, 1, color=cmap(norm(times[j])) ) ax.add_patch(rect) # 设置坐标轴和标签 ax.set_xticks(x_positions) ax.set_xticklabels(flux_groups['flux'].astype(str)) ax.set_xlabel('通量值') ax.set_ylabel('出现次数') ax.set_title('通量直方图(分段颜色对应时间)') # 添加颜色条 sm = cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) fig.colorbar(sm, ax=ax, label='时间') plt.tight_layout() plt.show()
关键细节说明
- 颜色映射部分:用
Normalize把时间值缩放到0-1的范围,这样就能对应到colormap的颜色区间。 - 每个小分段都是独立的矩形,通过循环逐个添加,能精准控制每个分段的颜色。
- 如果你的时间是日期格式,可以先把它转换成数值(比如Unix时间戳)再进行归一化。
如果一定要用Mathematica的话,其实也可以通过生成每个分段的Rectangle图形元素来实现,但步骤会繁琐很多,Python的这个方法更直观易调试。
内容的提问来源于stack exchange,提问作者megan_17
相关产品推荐
相关产品推荐

