grid zorder似乎没有生效(matplotlib)

时间:2015-07-19 21:58:08

标签: python matplotlib

我正在尝试使用python的matplotlib(1.4.3在网格上绘制散点图,但在其他版本上尝试也没有成功)。一切都有效,除了网格zorder位置。我将网格zorder设置为低于scatter,但网格仍然覆盖了散点。

这是一个重现问题的简单代码:

import numpy as np
from matplotlib import pyplot as plt

# create points
pnts = np.array([[1., 1.], [1., 1.2]])

# create figure
plt.grid(True, linestyle='-', color='r', zorder=1)
plt.scatter(pnts[:,0], pnts[:,1], zorder=2)
plt.ylim([0, 2])
plt.xlim([0, 2])
plt.savefig('testfig.png', dpi=350)

我明白了:
如果放大点,您可以看到网格位于顶部,尽管它有较低的zorderenter image description here

这是一个错误还是我做错了什么?

2 个答案:

答案 0 :(得分:2)

如果几年后仍然有人想知道这个问题(像我一样),这将是一个长期存在的问题(2015年9月):

Axes.grid() not honoring specified "zorder" kwarg

报价问题:

  

Axes.grid()不遵守提供的自定义zorder。取而代之的是,网格的zorder似乎固定在2.5到2.6之间的某个奇迹值(我在rcParams中找不到网格zorder的键)。

显然,到目前为止,唯一的解决方案是:

  

只需在所有z顺序中添加2.5。

此问题Matplotlib: draw grid lines behind other graph elements中也有一个旧答案,但似乎不再起作用。

答案 1 :(得分:1)

几年后,Gabriel 引用的 issue 已更新为以下内容,并于 2019 年 4 月关闭。

<块引用>

这必须是对刻度线和网格线系统进行大修的一部分,我怀疑这可能只是更重大重构的一个组成部分,所以我认为在可预见的未来的解决方案是文档调整在#13995

对于需要具有任意 zorder 值的网格的情况,一种解决方法是使用 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $mysqli = new mysqli("localhost", "root", "", "demo_db"); $sql = " SELECT id, question, category, type, difficulty, correct_answer, incorrect_answer_1, incorrect_answer_2, incorrect_answer_3 FROM questions Limit 50 "; $query = $mysqli->prepare($sql); $query->execute(); $result = $query->get_result(); $output = []; // Loop through the result set row by row while ($row = $result->fetch_assoc()) { $output[] = [ "category" => $row["category"], "type" => $row["type"], "difficulty" => $row["difficulty"], "question" => $row["question"], "correct_answer" => $row["correct_answer"], "incorrect_answers" => [ $row["incorrect_answer_1"], $row["incorrect_answer_2"], $row["incorrect_answer_3"], ], ]; } // Convert to JSON and print echo json_encode($output); 模拟 grid()。我编写了函数来尽可能地复制标准 grid() 行为(默认使用 rcParam 值)。

plot()

注意事项:

  1. 必须在调用 import matplotlib.pyplot as plt from matplotlib import rcParams import numpy as np # emulate grid using Axes.plot() def zorder_grid(ax=None, zorder=1.5, which=None, axis=None, alpha=None, color=None, linestyle=None, linewidth=None, **kwargs): # Honor rcParams values if keywords not specified if ax is None: ax = plt.gca() if which is None: which = rcParams['axes.grid.which'] if axis is None: axis = rcParams['axes.grid.axis'] if alpha is None: alpha = rcParams['grid.alpha'] if color is None: color = rcParams['grid.color'] if linestyle is None: linestyle = rcParams['grid.linestyle'] if linewidth is None: linewidth = rcParams['grid.linewidth'] # get coordinates for grid lines xlim = ax.get_xlim() ylim = ax.get_ylim() xticks = [] yticks = [] if which in ['major', 'both']: xticks = np.concatenate((xticks, ax.get_xticks())) yticks = np.concatenate((yticks, ax.get_yticks())) if which in ['minor', 'both']: xticks = np.concatenate((xticks, ax.get_xticks(minor=True))) yticks = np.concatenate((yticks, ax.get_yticks(minor=True))) # plot grid using Axes.plot() if axis in ['x', 'both']: for tick in xticks: ax.plot([tick, tick], ylim, linestyle=linestyle, color=color, linewidth=linewidth, alpha=alpha, zorder=zorder, **kwargs) if axis in ['y', 'both']: for tick in yticks: ax.plot(xlim, [tick, tick], linestyle=linestyle, color=color, linewidth=linewidth, alpha=alpha, zorder=zorder, **kwargs) 之前手动设置 x 和 y 限制。如果手动指定刻度,也需要在绘制网格线之前完成。
  2. 如果轴限制和/或刻度动态变化(例如动画),这将出现问题。可能的解决方案可能是清除帧之间的轴或返回 Line2D 列表并切换可见性。

可以按如下方式调用该函数以在 MWE 中生成所需的输出(任何 zorder < 1 都可以)。

zorder_grid()

上面代码生成的图。

Figure generated by the above code.