当前位置:首页>python>Nature 期刊图复现 | Python 实现肿瘤演化时间轴带置信区间的区间条形图

Nature 期刊图复现 | Python 实现肿瘤演化时间轴带置信区间的区间条形图

  • 2026-10-11 05:46:15
Nature 期刊图复现 | Python 实现肿瘤演化时间轴带置信区间的区间条形图

来源论文

论文地址:

https://www.nature.com/articles/s41586-023-06333-9

论文题目:

Evolutionary histories of breast cancer and related clones

原图释(英):c, Estimated timing of der(1;16) acquisition and MRCA emergence (only for premenopausal cases) is shown with the 95% CI. †, the first and second 1q gain timing were estimated because the order of der(1;16) and another 1q gain could not be determined in TMA125.
原图释(中):c,der(1;16)获得和MRCA出现(仅针对绝经前病例)均以95%置信区间显示。†,第一和第二位1q增益时序的估计是因为der(1;16)以及TMA125中无法确定另一个1q增益。

复现图片

图表含义

1. 肿瘤克隆演化生命轴 (Clonal Evolution Timeline):图中每一行代表一个独立的肿瘤克隆系(如 KU539、TMA125 等)。灰色的基底条横贯整个时间线,它象征着该克隆从诞生到患者手术切除的完整生命周期。通过观察条形的长短,我们可以直观判断肿瘤在患者体内的演化时长。

2. 遗传事件的时间窗口 (Genomic Event Intervals):条形图上叠加的彩色色块(粉色、绿色、蓝色)是图表的核心数据,分别代表了三次关键的基因组演变过程:

  • der(1;16) 畸变(粉色):揭示了染色体畸变发生的预测时间区间。

  • 基因组加倍(绿色):代表肿瘤细胞发生倍增的关键时刻。

  • 共同祖先出现(蓝色):标记了最近共同祖先(MRCA)的发生窗口。

这些色块的宽度即为 95% 置信区间(CI),反映了生物学推断的精确程度;色块内部的深色圆点则是统计学上的最优估计时间点。

3. 事件重叠与逻辑过渡 (Overlap and Transition):当不同生物学事件(如畸变与倍增)在时间上存在重叠时,通过精巧的色彩混合(如绿色与粉色混合生成的过渡色),直观展示了演化路径的复杂性和相关性。这种圆头设计的平滑过渡,避免了硬切口造成的视觉误解,精准呈现了肿瘤细胞在进化过程中的动态叠加状态。

4. 临床参照与分组特征 (Clinical Milestones and Grouping):

  1. 手术时间点 (Surgery):每一行生命条最右侧的紫色圆点,是绝对的“时间终点”,为所有遗传突变提供了一个共同的 clinical benchmark(临床参照点)。

  2. 绝经状态分组 (Menopausal Status):图表左侧的垂直色条(红色代表绝经前,黄色代表绝经后),将原本纯粹的分子数据与临床特征(患者年龄/内分泌状态)连接起来。这帮助研究者直观对比:在绝经状态发生变化前后,肿瘤演化的速度与顺序是否存在显著差异。

配色方案

color_palettes = {    1: { # 方案 1:原经典学术期刊配色 (默认激活)        'c_pre': '#E24A48', 'c_post': '#EBB02D', 'c_bg_bar': '#ECEFF1',        'c_der': '#F48FB1', 'c_der_dark': '#D81B60',        'c_mrca': '#b5c5e2', 'c_mrca_dark': '#1565C0',        'c_double': '#A5D6A7', 'c_double_dark': '#1B5E20',        'c_grey_overlap': '#B0BEC5', 'c_mix_overlap': '#8FBC8F',        'c_mrca_overlap': '#7f9cb5', 'c_surgery': '#7B1FA2'    },    2: { # 方案 2:Nature 风格经典高级红蓝        'c_pre': '#E64B35', 'c_post': '#4DBBD5', 'c_bg_bar': '#F5F5F5',        'c_der': '#F39B7F', 'c_der_dark': '#BC3C29',        'c_mrca': '#8491B4', 'c_mrca_dark': '#3C5488',        'c_double': '#91D1C2', 'c_double_dark': '#00A087',        'c_grey_overlap': '#CCCCCC', 'c_mix_overlap': '#A2BFC1',        'c_mrca_overlap': '#8E9AA6', 'c_surgery': '#7E6148'    },    3: { # 方案 3:Science 风格高对比冷调        'c_pre': '#111E6C', 'c_post': '#D96B27', 'c_bg_bar': '#EEF2F7',        'c_der': '#A0C4DF', 'c_der_dark': '#00468B',        'c_mrca': '#B19FFB', 'c_mrca_dark': '#42150A',        'c_double': '#97D7BF', 'c_double_dark': '#0099B4',        'c_grey_overlap': '#D1D5DB', 'c_mix_overlap': '#9EBDB2',        'c_mrca_overlap': '#A79EC4', 'c_surgery': '#925E9F'    },    4: { # 方案 4:Cell 研学热烈风格        'c_pre': '#A73030', 'c_post': '#4A6984', 'c_bg_bar': '#F7F7F7',        'c_der': '#F4A261', 'c_der_dark': '#E76F51',        'c_mrca': '#A8DADC', 'c_mrca_dark': '#1D3557',        'c_double': '#CCD5AE', 'c_double_dark': '#606C38',        'c_grey_overlap': '#E5E5E5', 'c_mix_overlap': '#BAC09A',        'c_mrca_overlap': '#A2B5C1', 'c_surgery': '#E63946'    },    5: { # 方案 5:The Lancet 柳叶刀沉稳高雅        'c_pre': '#006666', 'c_post': '#C0392B', 'c_bg_bar': '#F2F4F4',        'c_der': '#A3E4D7', 'c_der_dark': '#16A085',        'c_mrca': '#AED6F1', 'c_mrca_dark': '#2980B9',        'c_double': '#F9E79F', 'c_double_dark': '#D4AC0D',        'c_grey_overlap': '#BDC3C7', 'c_mix_overlap': '#CFD8A8',        'c_mrca_overlap': '#A5C1DC', 'c_surgery': '#8E44AD'    },    6: { # 方案 6:JAMA 现代医学低饱和度        'c_pre': '#34495E', 'c_post': '#E67E22', 'c_bg_bar': '#F8F9F9',        'c_der': '#ABB2B9', 'c_der_dark': '#2C3E50',        'c_mrca': '#A9DFBF', 'c_mrca_dark': '#27AE60',        'c_double': '#F9E79F', 'c_double_dark': '#D35400',        'c_grey_overlap': '#E5E7E9', 'c_mix_overlap': '#D5CB9E',        'c_mrca_overlap': '#99C7A5', 'c_surgery': '#9B59B6'    },    7: { # 方案 7:复古莫兰迪高级灰色调        'c_pre': '#C2B280', 'c_post': '#848482', 'c_bg_bar': '#EAEAEA',        'c_der': '#E6A8A8', 'c_der_dark': '#B36B6B',        'c_mrca': '#A3C1AD', 'c_mrca_dark': '#6B8E23',        'c_double': '#D2B48C', 'c_double_dark': '#8B5A2B',        'c_grey_overlap': '#D8D8D8', 'c_mix_overlap': '#BBA795',        'c_mrca_overlap': '#98B1A2', 'c_surgery': '#704242'    },    8: { # 方案 8:柔和马卡龙少女粉蓝绿        'c_pre': '#FFB7B2', 'c_post': '#BFFCC6', 'c_bg_bar': '#FAFAFA',        'c_der': '#FFD1DC', 'c_der_dark': '#FF69B4',        'c_mrca': '#E8A7A1', 'c_mrca_dark': '#CD5C5C',        'c_double': '#C7CEEA', 'c_double_dark': '#6A5ACD',        'c_grey_overlap': '#EDEDED', 'c_mix_overlap': '#DDCEE2',        'c_mrca_overlap': '#D6B9C5', 'c_surgery': '#FFDAC1'    },    9: { # 方案 9:经典灰度印刷风格 (黑白论文首选)        'c_pre': '#333333', 'c_post': '#777777', 'c_bg_bar': '#F0F0F0',        'c_der': '#CCCCCC', 'c_der_dark': '#111111',        'c_mrca': '#DDDDDD', 'c_mrca_dark': '#444444',        'c_double': '#B5B5B5', 'c_double_dark': '#222222',        'c_grey_overlap': '#E0E0E0', 'c_mix_overlap': '#C0C0C0',        'c_mrca_overlap': '#CECECE', 'c_surgery': '#000000'    },    10: { # 方案 10:海洋深邃蓝青色系        'c_pre': '#0077B6', 'c_post': '#00B4D8', 'c_bg_bar': '#F0F8FF',        'c_der': '#90E0EF', 'c_der_dark': '#03045E',        'c_mrca': '#CAF0F8', 'c_mrca_dark': '#0096C7',        'c_double': '#A8E6CF', 'c_double_dark': '#20B2AA',        'c_grey_overlap': '#E6F2F7', 'c_mix_overlap': '#99D5CC',        'c_mrca_overlap': '#AFDBCF', 'c_surgery': '#48CAE4'    },    11: { # 方案 11:森林大地自然绿棕        'c_pre': '#2C5E3B', 'c_post': '#8B5A2B', 'c_bg_bar': '#F4F7F4',        'c_der': '#A2CD5A', 'c_der_dark': '#556B2F',        'c_mrca': '#EEDC82', 'c_mrca_dark': '#8B7500',        'c_double': '#CDA077', 'c_double_dark': '#5C4033',        'c_grey_overlap': '#E3ECE3', 'c_mix_overlap': '#B2B36B',        'c_mrca_overlap': '#D6CC7B', 'c_surgery': '#8FBC8F'    },    12: { # 方案 12:暖阳秋日橙黄暖调        'c_pre': '#D35400', 'c_post': '#F1C40F', 'c_bg_bar': '#FEF9E7',        'c_der': '#EDBB99', 'c_der_dark': '#BA4A00',        'c_mrca': '#F9E79F', 'c_mrca_dark': '#B7950B',        'c_double': '#F5B041', 'c_double_dark': '#A04000',        'c_grey_overlap': '#F9EBEA', 'c_mix_overlap': '#F0B46A',        'c_mrca_overlap': '#F6CA87', 'c_surgery': '#C0392B'    },    13: { # 方案 13:霓虹极光高亮配色        'c_pre': '#FF007F', 'c_post': '#00FFFF', 'c_bg_bar': '#FAFAFA',        'c_der': '#FF7F00', 'c_der_dark': '#FF3300',        'c_mrca': '#7F00FF', 'c_mrca_dark': '#4B0082',        'c_double': '#00FF00', 'c_double_dark': '#006600',        'c_grey_overlap': '#EEEEEE', 'c_mix_overlap': '#66CC44',        'c_mrca_overlap': '#3F6680', 'c_surgery': '#FFD700'    },    14: { # 方案 14:商务经典沉稳深红深蓝        'c_pre': '#1B365D', 'c_post': '#8B2635', 'c_bg_bar': '#F0F4F8',        'c_der': '#708090', 'c_der_dark': '#2F4F4F',        'c_mrca': '#9FA8DA', 'c_mrca_dark': '#3F51B5',        'c_double': '#9CCC65', 'c_double_dark': '#558B2F',        'c_grey_overlap': '#E2E8F0', 'c_mix_overlap': '#88A260',        'c_mrca_overlap': '#99A5C7', 'c_surgery': '#D32F2F'    },    15: { # 方案 15:冰川北欧高冷纯净        'c_pre': '#4A6B82', 'c_post': '#A3B8CC', 'c_bg_bar': '#FAFCFD',        'c_der': '#DCE5EC', 'c_der_dark': '#2C3E50',        'c_mrca': '#C4D4E1', 'c_mrca_dark': '#1F3A52',        'c_double': '#B0C4DE', 'c_double_dark': '#4682B4',        'c_grey_overlap': '#EBF1F5', 'c_mix_overlap': '#BFCEDB',        'c_mrca_overlap': '#B9C9D7', 'c_surgery': '#778899'    },    16: { # 方案 16:夕阳余晖温和粉紫        'c_pre': '#9B59B6', 'c_post': '#F39C12', 'c_bg_bar': '#FBEEE6',        'c_der': '#FADBD8', 'c_der_dark': '#E74C3C',        'c_mrca': '#EBDEF0', 'c_mrca_dark': '#8E44AD',        'c_double': '#FDEBD0', 'c_double_dark': '#D35400',        'c_grey_overlap': '#FDEDEC', 'c_mix_overlap': '#FCB6D0',        'c_mrca_overlap': '#ECC8E0', 'c_surgery': '#34495E'    },    17: { # 方案 17:科技前沿明亮钛灰        'c_pre': '#212121', 'c_post': '#00E5FF', 'c_bg_bar': '#FAFAFA',        'c_der': '#B0BEC5', 'c_der_dark': '#37474F',        'c_mrca': '#80DEEA', 'c_mrca_dark': '#00838F',        'c_double': '#B2FF59', 'c_double_dark': '#4E9D24',        'c_grey_overlap': '#ECEFF1', 'c_mix_overlap': '#B1DE71',        'c_mrca_overlap': '#97CED9', 'c_surgery': '#FF5252'    },    18: { # 方案 18:波尔多古典红酒香槟        'c_pre': '#581845', 'c_post': '#FFC300', 'c_bg_bar': '#F9F2F5',        'c_der': '#C70039', 'c_der_dark': '#900C3F',        'c_mrca': '#FF5733', 'c_mrca_dark': '#C70039',        'c_double': '#FF8D1A', 'c_double_dark': '#A34E00',        'c_grey_overlap': '#EAECEE', 'c_mix_overlap': '#E04E27',        'c_mrca_overlap': '#FA6D35', 'c_surgery': '#2C3E50'    },    19: { # 方案 19:英伦庄园下午茶灰绿复古        'c_pre': '#556B2F', 'c_post': '#CD853F', 'c_bg_bar': '#FDFBF7',        'c_der': '#BC8F8F', 'c_der_dark': '#8B4513',        'c_mrca': '#8FBC8F', 'c_mrca_dark': '#2E8B57',        'c_double': '#BDB76B', 'c_double_dark': '#6B8E23',        'c_grey_overlap': '#F0E68C', 'c_mix_overlap': '#A2A56C',        'c_mrca_overlap': '#8E9C73', 'c_surgery': '#483D8B'    },    20: { # 方案 20:浆果森林高保真浆果红        'c_pre': '#6B114D', 'c_post': '#11536B', 'c_bg_bar': '#FBF6F9',        'c_der': '#D982B5', 'c_der_dark': '#A62466',        'c_mrca': '#72B0C4', 'c_mrca_dark': '#0B637F',        'c_double': '#94D2BD', 'c_double_dark': '#1A7A66',        'c_grey_overlap': '#EAF2F4', 'c_mix_overlap': '#83BCA2',        'c_mrca_overlap': '#81C1C4', 'c_surgery': '#E76F51'    }}

完整代码

import osimport numpy as npimport pandas as pdimport matplotlib.pyplot as plt# 1. 自动创建 图表 文件夹output_dir = "图表"os.makedirs(output_dir, exist_ok=True)# 2. 自动读取同目录下的 data.xlsxexcel_file = "data.xlsx"if not os.path.exists(excel_file):    raise FileNotFoundError(f"未在当前目录下找到 {excel_file},请确保该 Excel 文件存在。")df = pd.read_excel(excel_file)# 3. 匹配 Excel 列名映射mapping = {    'clone': 'clone',    'age': 'age',    'menopausal_status': 'menopausal_status',    'est_der': 'estimates for der(1;16) timing',    'low_der': 'lower CI for der(1;16) timing',    'upp_der': 'upper CI for der(1;16) acquision',    'est_doub': 'estimates for der(1;16) doubling timing',    'low_doub': 'lower CI for der(1;16) doubling timing',    'upp_doub': 'upper CI for der(1;16) doubling timing',    'est_mrca': 'estimates for MRCA timing',    'low_mrca': 'lower CI for MRCA timing',    'upp_mrca': 'upper CI for MRCA timing'}# 4. 格式化克隆系名称def format_clone_name(row):    name = str(row[mapping['clone']]).strip()    if 'KU539_a' in name or 'KU539a' in name or 'clone α' in name: return 'KU539\n(clone α)'    if 'KU539_b' in name or 'KU539b' in name or 'clone β' in name: return 'KU539\n(clone β)'    if 'KU779_a' in name or 'KU779a' in name or 'clone α' in name: return 'KU779\n(clone α)'    if 'KU779_b' in name or 'KU779b' in name or 'clone β' in name: return 'KU779\n(clone β)'    if 'TMA125' in name: return 'TMA125 †'    return namedf['display_name'] = df.apply(format_clone_name, axis=1)# 为了让左侧刻度最下方是 TMA149,最上方是 KU957,将 DataFrame 颠倒df = df.iloc[::-1].reset_index(drop=True)# 5. 20种学术与商务图表配色方案字典color_palettes = {    1: { # 方案 1:原经典学术期刊配色 (默认激活)        'c_pre': '#E24A48', 'c_post': '#EBB02D', 'c_bg_bar': '#ECEFF1',        'c_der': '#F48FB1', 'c_der_dark': '#D81B60',        'c_mrca': '#b5c5e2', 'c_mrca_dark': '#1565C0',        'c_double': '#A5D6A7', 'c_double_dark': '#1B5E20',        'c_grey_overlap': '#B0BEC5', 'c_mix_overlap': '#8FBC8F',        'c_mrca_overlap': '#7f9cb5', 'c_surgery': '#7B1FA2'    }}# 提取选择的配色方案 (此处默认应用方案 1)current_palette_id = 1palette = color_palettes[current_palette_id]c_pre = palette['c_pre']c_post = palette['c_post']c_bg_bar = palette['c_bg_bar']c_der = palette['c_der']c_der_dark = palette['c_der_dark']c_mrca = palette['c_mrca']c_mrca_dark = palette['c_mrca_dark']c_double = palette['c_double']c_double_dark = palette['c_double_dark']c_grey_overlap = palette['c_grey_overlap']c_mix_overlap = palette['c_mix_overlap']c_mrca_overlap = palette['c_mrca_overlap']c_surgery = palette['c_surgery']# 6. 初始化画布fig, ax = plt.subplots(figsize=(8.0, 7.0), dpi=300)# 控制绘图视窗,放宽上方给指示标签留出独立区域ax.set_xlim(-6, 80)ax.set_ylim(-0.8, len(df) + 0.8)ax.set_xlabel('Age (years)', fontsize=10, fontname='DejaVu Sans', labelpad=5)ax.set_xticks(range(0, 90, 10))ax.set_xticklabels(range(0, 90, 10))ax.tick_params(axis='x', labelsize=9)# 隐藏上方和右侧边框ax.spines['top'].set_visible(False)ax.spines['right'].set_visible(False)# 左侧轴和下方轴彻底断开不交叉ax.spines['left'].set_visible(True)ax.spines['left'].set_bounds(0, len(df) - 1)ax.spines['left'].set_linewidth(0.8)ax.spines['bottom'].set_visible(True)ax.spines['bottom'].set_bounds(0, 80)ax.spines['bottom'].set_linewidth(0.8)# 设置刻度样式朝外突出ax.tick_params(axis='both', which='both', direction='out', length=4, width=0.8, colors='black')# 7. 核心绘图逻辑y_positions = np.arange(len(df))lw_val = 9  # 恢复标准好看的生命条粗细for i, row in df.iterrows():    y = i    max_age = row[mapping['age']]    clone_id = str(row[mapping['clone']])    # A. 基础背景生命条    ax.plot([0, max_age], [y, y], color=c_bg_bar, linewidth=lw_val, solid_capstyle='round', zorder=1)    # 提取各区间真实数据    est_der = row[mapping['est_der']]    low_der = row[mapping['low_der']]    upp_der = row[mapping['upp_der']]    est_doub = row[mapping['est_doub']]    low_doub = row[mapping['low_doub']]    upp_doub = row[mapping['upp_doub']]    est_mrca = row[mapping['est_mrca']]    low_mrca = row[mapping['low_mrca']]    upp_mrca = row[mapping['upp_mrca']]    # B. der(1;16) 区间(恢复完美的原生 round 圆头)    if not pd.isna(est_der):        ax.plot([low_der, upp_der], [y, y], color=c_der, linewidth=lw_val, solid_capstyle='round', zorder=2)        ax.scatter(est_der, y, color=c_der_dark, s=30, zorder=5)    # C. 特定的灰色重叠过渡段    if 'KU957' in clone_id or 'TMA125' in clone_id:        if not pd.isna(est_doub):            ax.plot([est_der, est_doub], [y, y], color=c_grey_overlap, linewidth=lw_val, solid_capstyle='butt',                    zorder=2.5)    # D. doubling 倍增区间(恢复完美的原生 round 圆头)    if not pd.isna(est_doub):        ax.plot([low_doub, upp_doub], [y, y], color=c_double, linewidth=lw_val, solid_capstyle='round', zorder=3)        ax.scatter(est_doub, y, color=c_double_dark, s=30, zorder=5)    # 重叠区域(含边缘圆头部分)采用完美匹配的覆盖混色    if not pd.isna(low_der) and not pd.isna(low_doub):        overlap_start = max(low_der, low_doub)        overlap_end = min(upp_der, upp_doub)        if overlap_start < overlap_end:            # 使用 round 让重叠部分的端点圆头也自然过渡变色,不会变形            ax.plot([overlap_start, overlap_end], [y, y], color=c_mix_overlap, linewidth=lw_val, solid_capstyle='round',                    zorder=3.6)    # E. MRCA occurrence 区间    if not pd.isna(est_mrca):        ax.plot([low_mrca, upp_mrca], [y, y], color=c_mrca, linewidth=lw_val, solid_capstyle='round', zorder=4)        ax.scatter(est_mrca, y, color=c_mrca_dark, s=30, zorder=5)    # MRCA 与 doubling 发生区域重叠时的完美圆头混色    if not pd.isna(low_mrca) and not pd.isna(low_doub):        overlap_start = max(low_mrca, low_doub)        overlap_end = min(upp_mrca, upp_doub)        if overlap_start < overlap_end:            ax.plot([overlap_start, overlap_end], [y, y], color=c_mrca_overlap, linewidth=lw_val,                    solid_capstyle='round', zorder=4.6)    # F. Surgery 紫色圆点    ax.scatter(max_age, y, color=c_surgery, s=30, zorder=6)# 8. 绝经状态垂直双色条status_col = df[mapping['menopausal_status']].str.lower()pre_indices = df[status_col.str.contains('pre', na=False)].indexpost_indices = df[status_col.str.contains('post', na=False)].indexif len(pre_indices) > 0:    ax.fill_betweenx([pre_indices.min() - 0.35, pre_indices.max() + 0.35], -4.5, -3.5, color=c_pre, zorder=10)if len(post_indices) > 0:    ax.fill_betweenx([post_indices.min() - 0.35, post_indices.max() + 0.35], -4.5, -3.5, color=c_post, zorder=10)ax.set_yticks(y_positions)ax.set_yticklabels(df['display_name'], fontsize=9, fontname='DejaVu Sans', va='center')ax.tick_params(axis='y', pad=6)# 9. 重要修复:文字右对齐与左对齐 顶部上方区域绘制y_top_line1 = len(df) + 0.35y_top_line2 = len(df) - 0.15# 通过减小这两个值,将整个标签区域整体向左移动(例如分别改到 0.5 和 4.0)x_text_right_align = 0.5   # 左边两行单词的右对齐基准线(值越小越靠左)x_block_left_align = 4.0   # 右边指示方块的左对齐基准线(值越小越靠左)# 1. 上方行:Menopausal (右对齐)  ->  ■ Premenopausal (左对齐)ax.text(x_text_right_align, y_top_line1, 'Menopausal', fontsize=9, ha='right', va='top', fontname='DejaVu Sans', weight='bold')ax.text(x_block_left_align, y_top_line1, '■ Premenopausal', color=c_pre, fontsize=9, ha='left', va='top', weight='bold')# 2. 下方行:status (右对齐)  ->  ■ Postmenopausal (左对齐)ax.text(x_text_right_align, y_top_line2, 'status', fontsize=9, ha='right', va='top', fontname='DejaVu Sans', weight='bold')ax.text(x_block_left_align, y_top_line2, '■ Postmenopausal', color=c_post, fontsize=9, ha='left', va='top', weight='bold')# 10. 底部的双列图例(保持左移对齐 + 优雅下移)y_leg1 = -2.4y_leg2 = -3.2ax.plot([-4.5, 2.5], [y_leg1, y_leg1], color=c_der, linewidth=9, solid_capstyle='round', clip_on=False)ax.scatter(-1.0, y_leg1, color=c_der_dark, s=30, zorder=10, clip_on=False)ax.text(4.5, y_leg1, 'der(1;16)', fontsize=9, va='center', ha='left')ax.plot([-4.5, 2.5], [y_leg2, y_leg2], color=c_mrca, linewidth=9, solid_capstyle='round', clip_on=False)ax.scatter(-1.0, y_leg2, color=c_mrca_dark, s=30, zorder=10, clip_on=False)ax.text(4.5, y_leg2, 'MRCA occurence', fontsize=9, va='center', ha='left')ax.plot([33, 41], [y_leg1, y_leg1], color=c_double, linewidth=9, solid_capstyle='round', clip_on=False)ax.scatter(37, y_leg1, color=c_double_dark, s=30, zorder=10, clip_on=False)ax.text(43, y_leg1, 'der(1;16) doubling', fontsize=9, va='center', ha='left')ax.scatter(37, y_leg2, color=c_surgery, s=30, zorder=10, clip_on=False)ax.text(43, y_leg2, 'Surgery', fontsize=9, va='center', ha='left')# 11. 将序号 'c' 置于最左上角fig.text(0.07, 0.93, 'c', fontsize=18, weight='bold', fontname='DejaVu Sans', va='top', ha='left')# 12. 保存图片plt.subplots_adjust(bottom=0.25, left=0.16, right=0.95, top=0.90)output_path = os.path.join(output_dir, "timeline_plot.png")plt.savefig(output_path, bbox_inches='tight')plt.close()print(f"Plot saved successfully to {output_path}")

数据获取

评论+私信获取

最新文章

随机文章