如何在Matplotlib中将x轴刻度与刻度标签向上移动并支持自定义调整
实现方案
可以通过新增可配置的偏移参数,同步调整x轴刻度和标签的垂直位置,具体修改如下:
修改点说明
- 在
CircleHeatmap类的初始化参数中新增x_tick_offset,数值为正代表向上偏移的幅度,默认值为0即不偏移 - 在
labels方法中补充偏移逻辑,可根据需求同时调整刻度线与标签的y轴位置
完整修改后代码
import matplotlib.pyplot as plt import matplotlib.colors as mcl import numpy as np import pandas as pd from typing import List, T from random import uniform def l_flatten(l: List[T]) -> List[T]: return [j for i in l for j in i] def get_luminance(color: str) -> float: # taken from Seaborn's utils rgb = mcl.colorConverter.to_rgba_array(color)[:, :3] rgb = np.where(rgb <= .03928, rgb / 12.92, ((rgb + .055) / 1.055) ** 2.4) lum = rgb.dot([.2126, .7152, .0722]) try: lum = lum.item() except ValueError: pass return lum class CircleHeatmap: def __init__(self, ax: plt.Axes, df: pd.DataFrame, colors: List[str], annot_show: bool, annot_size: float, circle_size: float, x_labels: List[str], x_labels_size: float, x_labels_color: str, y_labels: List[str], y_labels_size: float, y_labels_color: str, x_tick_offset: float = 0.0) -> None: # pass user-provided variables self.ax = ax self.df = df self.colors = colors self.annot_show = annot_show self.annot_size = annot_size self.circle_size = circle_size self.x_labels = x_labels self.x_labels_size = x_labels_size self.x_labels_color = x_labels_color self.y_labels = y_labels self.y_labels_size = y_labels_size self.y_labels_color = y_labels_color self.x_tick_offset = x_tick_offset # pass technical variables self.y_size, self.x_size = self.df.shape self.x_arr, self.y_arr = np.meshgrid(np.arange(self.x_size), np.arange(self.y_size)) self.x_arr, self.y_arr = ((self.x_arr + 0.5).flat, (self.y_arr + 0.5).flat) self.x_len, self.y_len = [np.linspace(0, len(i), len(i) + 1)[:-1] + 0.5 for i in (self.x_labels, self.y_labels)] self.df_values = l_flatten(self.df.values.tolist()) def plot(self) -> None: self.ax.scatter(self.x_arr, self.y_arr, s = self.circle_size ** 2, c = self.colors) def labels(self) -> None: self.ax.set_xticks(self.x_len) self.ax.set_yticks(self.y_len) self.ax.set_xticklabels(self.x_labels, fontsize = self.x_labels_size, color = self.x_labels_color) self.ax.set_yticklabels(self.y_labels, fontsize = self.y_labels_size, color = self.y_labels_color) # 调整x轴标签向上偏移 for xtick in self.ax.get_xticklabels(): xtick.set_y(xtick.get_position()[1] + self.x_tick_offset) # 如果需要显示刻度线并同步偏移,可取消下面一行的注释 # self.ax.tick_params(axis='x', offset=self.x_tick_offset * 72) def main() -> None: fig, ax = plt.subplots(figsize = (20, 30)) df = pd.DataFrame([[uniform(0, 1) for j in range(20)] for i in range(30)]) colors = ["#EC4E20", "#FF9505", "#016FB9"] * 200 heatmap = CircleHeatmap(ax = ax, df = df, colors = colors, annot_show = False, annot_size = 16, circle_size = 45, x_labels = [i for i in range(20)], x_labels_size = 20, x_labels_color = "black", y_labels = [i for i in range(30)], y_labels_size = 20, y_labels_color = "black", x_tick_offset = 0.2) # 可自行调整该数值控制上移幅度 heatmap.plot() heatmap.labels() for i in ["top", "bottom", "right", "left"]: ax.spines[i].set_visible(False) plt.savefig("test2.png") if __name__ == "__main__": main()
调整方法
你可以修改实例化CircleHeatmap时传入的x_tick_offset数值,数值越大上移幅度越大,比如可尝试0.1、0.3等数值,直到位置符合预期。
内容的提问来源于stack exchange,提问作者Gleb Ryabov
相关产品推荐
相关产品推荐

