matplotlib 可以打印网格交叉而不是绘图上的网格线吗? [英] Instead of grid lines on a plot, can matplotlib print grid crosses?

查看:73
本文介绍了matplotlib 可以打印网格交叉而不是绘图上的网格线吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在绘图上有一些网格线,但实际上全长线太多/分散注意力,甚至是浅灰色虚线.我去了,并手动对SVG输出进行了一些编辑以获得我想要的效果.可以使用matplotlib完成吗?我看了网格的pyplot api,我唯一能看到的可能就是xdata和ydata Line2D kwargs.

I want to have some grid lines on a plot, but actually full-length lines are too much/distracting, even dashed light grey lines. I went and manually did some editing of the SVG output to get the effect I was looking for. Can this be done with matplotlib? I had a look at the pyplot api for grid, and the only thing I can see that might be able to get near it are the xdata and ydata Line2D kwargs.

推荐答案

这无法通过基本 API 完成,因为网格线仅使用两个点创建.网格线在每个刻度线上都需要一个数据"点,以便绘制标记.在下面的示例中显示:

This cannot be done through the basic API, because the grid lines are created using only two points. The grid lines would need a 'data' point at every tick mark for there to be a marker drawn. This is shown in the following example:

import matplotlib.pyplot as plt

ax = plt.subplot(111)
ax.grid(clip_on=False, marker='o', markersize=10)
plt.savefig('crosses.png')
plt.show()

结果是:

请注意 'o' 标记如何仅位于 Axes 边缘的开头和结尾,因为网格线仅涉及两个点.

Notice how the 'o' markers are only at the beginning and the end of the Axes edges, because the grid lines only involve two points.

您可以编写一种方法来模拟您想要的东西,使用一系列Artists 创建十字标记,但仅利用基本绘图功能来绘制十字图案会更快.

You could write a method to emulate what you want, creating the cross marks using a series of Artists, but it's quicker to just leverage the basic plotting capabilities to draw the cross pattern.

这就是我在以下示例中所做的:

This is what I do in the following example:

import matplotlib.pyplot as plt
import numpy as np

NPOINTS=100

def set_grid_cross(ax, in_back=True):
    xticks = ax.get_xticks()
    yticks = ax.get_yticks()
    xgrid, ygrid = np.meshgrid(xticks, yticks)
    kywds = dict() 
    if in_back:
        kywds['zorder'] = 0
    grid_lines = ax.plot(xgrid, ygrid, 'k+', **kywds)

xvals = np.arange(NPOINTS)
yvals = np.random.random(NPOINTS) * NPOINTS

ax1 = plt.subplot(121)
ax2 = plt.subplot(122)

ax1.plot(xvals, yvals, linewidth=4)
ax1.plot(xvals, xvals, linewidth=7)
set_grid_cross(ax1)
ax2.plot(xvals, yvals, linewidth=4)
ax2.plot(xvals, xvals, linewidth=7)
set_grid_cross(ax2, in_back=False)

plt.savefig('gridpoints.png')
plt.show()

这将导致下图:

如您所见,我在x和y中打勾,以定义要在其上添加网格标记('+')的一系列点.我使用 meshgrid 获取两个一维数组,并根据每个网格点上的双循环制作 2 个二维数组.我用标记样式为 '+' 绘制它,我就完成了......几乎.这在顶部绘制了十字形,我添加了一个额外的关键字来重新排序与该图相关联的线的列表.如果要在所有内容后面绘制网格标记,我会调整它们的 zorder.*****

As you can see, I take the tick marks in x and y to define a series of points where I want grid marks ('+'). I use meshgrid to take two 1D arrays and make 2 2D arrays corresponding to the double loop over each grid point. I plot this with the mark style as '+', and I'm done... almost. This plots the crosses on top, and I added an extra keyword to reorder the list of lines associated with the plot. I adjust the zorder of the grid marks if they are to be drawn behind everything.*****

该示例显示了默认情况下将网格放在后面的左侧子图,而右侧子图禁用了此选项.如果您遵循每个图中的绿线,您会注意到差异.

The example shows the left subplot where by default the grid is placed in back, and the right subplot disables this option. You can notice the difference if you follow the green line in each plot.

如果由于在边界上有网格交叉而感到困扰,则可以在 set_grid_cross 中定义网格之前删除x和y的第一个和最后一个刻度线,如下所示:

If you are bothered by having grid crosses on the boarder, you can remove the first and last tick marks for both x and y before you define the grid in set_grid_cross, like so:

xticks = ax.get_xticks()[1:-1] #< notice the slicing
yticks = ax.get_yticks()[1:-1] #< notice the slicing
xgrid, ygrid = np.meshgrid(xticks, yticks)

在下面的示例中,我使用一个更大的不同标记来说明我的观点:

I do this in the following example, using a larger, different marker to make my point:

***** 感谢@fraxel 的回答指出这一点.

***** Thanks to the answer by @fraxel for pointing this out.

这篇关于matplotlib 可以打印网格交叉而不是绘图上的网格线吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆