Matplotlib重绘文本变换效果及庞尼特方图坐标轴标签旋转问题
Matplotlib自定义标签与transData使用说明
transData接口说明
Axes.transData是Matplotlib官方公开的坐标变换对象,核心功能是实现数据坐标到画布显示坐标的映射,配套的transform()方法可以将输入的数据坐标点转换为对应的画布像素坐标,相关说明可以在Matplotlib官方文档的变换教程章节查询。
需求实现代码
你需要实现的-90度旋转轴标签、侧边展示性别标签、底部标签在右侧重复展示的需求,调整原有代码的文本位置和变换参数即可,完整可运行代码如下:
import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D from matplotlib.patches import Rectangle plt.close("all") fig, ax0 = plt.subplots(1, 1, figsize=(8, 8)) dim = 1000 tl_margin = 75 br_margin = 50 tau = 0.90 rho = 0.60 # 矩形区域配置 rect_positions = { "ffv": { "anchor": (0., 0.), "height": rho * tau * dim, "width": rho * tau * dim, "color": "#ff00ff", "alpha": 0.6 }, "ffh": { "anchor": (rho * tau * dim, rho * tau * dim), "height": rho * (1 - tau) * dim, "width": rho * (1 - tau) * dim, "color": "#ffff00", "alpha": 0.6 }, "mmh": { "anchor": (rho * dim + (1 - rho) * tau * dim, rho * dim + (1 - rho) * tau * dim), "width": (1 - rho) * (1 - tau) * dim, "height": (1 - rho) * (1 - tau) * dim, "color": "#0000ff", "alpha": 0.6 } } # 标签位置配置 label_positions = { "female": { "sex": {"pos": rho * dim / 2, "symbol": "female"}, "transmission": { "vertical": {"pos": rho * tau * dim / 2, "symbol": "v"}, "horizontal": {"pos": rho * tau * dim + rho * (1 - tau) * dim / 2, "symbol": "h"} } }, "male": { "sex": {"pos": rho * dim + (1 - rho) * dim / 2, "symbol": "male"}, "transmission": { "vertical": {"pos": rho * dim + (1 - rho) * tau * dim / 2, "symbol": "v"}, "horizontal": {"pos": rho * dim + (1 - rho) * tau * dim + (1 - tau) * (1 - rho) * dim / 2, "symbol": "h"} } } } # 坐标轴配置 ax0.set_xlim(-tl_margin, dim + br_margin) ax0.set_ylim(-br_margin, dim + tl_margin) ax0.set_aspect(1) ax0.set_xticks(()) ax0.set_yticks(()) # 绘制边框 ax0.hlines((0, dim), 0, dim) ax0.vlines((0, dim), 0, dim) # 绘制功能区块 for value in rect_positions.values(): ax0.add_patch(Rectangle( value["anchor"], value["height"], value["width"], color=value["color"], alpha=value["alpha"] )) # 绘制性别比例分割线 ax0.hlines(rho * dim, -tl_margin, dim + br_margin, color="black", linestyle="--") ax0.vlines(rho * dim, -br_margin, dim + tl_margin, color="black", linestyle="--") # 绘制传播模式分割线 ax0.hlines( (tau * rho * dim, rho * dim + tau * (1 - rho) * dim), 0, dim + br_margin, color="black" ) ax0.vlines( (tau * rho * dim, rho * dim + tau * (1 - rho) * dim), -br_margin, dim, color="black" ) label_offset = 25 # 顶部性别标签(水平) for sex_label in label_positions.values(): ax0.text( sex_label["sex"]["pos"], dim + label_offset, sex_label["sex"]["symbol"], va="center", ha="center", color="black" ) # 左侧性别标签(-90度旋转) left_rotate = ax0.transData + Affine2D().rotate_deg(-90) for sex_label in label_positions.values(): ax0.text( -label_offset, sex_label["sex"]["pos"], sex_label["sex"]["symbol"], va="center", ha="center", color="black", transform=left_rotate ) # 底部传播模式标签(水平) for sex_label in label_positions.values(): for symbol in sex_label["transmission"].values(): ax0.text( symbol["pos"], -label_offset, symbol["symbol"], va="center", ha="center", color="black" ) # 右侧传播模式标签(-90度旋转) right_rotate = ax0.transData + Affine2D().rotate_deg(-90) for sex_label in label_positions.values(): for symbol in sex_label["transmission"].values(): ax0.text( dim + label_offset, symbol["pos"], symbol["symbol"], va="center", ha="center", color="black", transform=right_rotate ) plt.show()
运行后得到的效果如下:
内容的提问来源于stack exchange,提问作者mnosefish
相关产品推荐
相关产品推荐

