Python Matplotlib:如何使轴刻度线独立于网格线?

Python Matplotlib: How to make axis tick marks independent of grid lines?

您好,感谢您的提前帮助!

这是我使用的代码:

import matplotlib.pyplot as plt

# Sample of data being read in
x1 = [7.000000000000000000e+00,
      4.000000000000000222e-01,
      2.000000000000000111e-01,
      1.000000000000000000e+01,
      6.999999999999999556e-01,
      6.999999999999999556e-01,
      1.300000000000000044e+00,
      2.000000000000000111e-01,
      1.130000000000000071e+01,
      2.000000000000000111e-01,
      4.000000000000000222e-01,
      4.099999999999999645e+00,
      7.900000000000000355e+00,
      2.999999999999999889e-01,
      4.000000000000000000e+00]
y1 = [6.599999999999999645e+00,
      5.400000000000002132e+00,
      1.509999999999999787e+00,
      -2.999999999999989342e-01,
      5.500000000000000000e+00,
      1.759999999999999787e+00,
      5.500000000000000888e+00,
      2.299999999999995381e-01,
      3.380000000000000782e+00,
      2.280000000000001137e+00,
      4.910000000000000142e+00,
      3.849999999999999645e+00,
      5.500000000000000888e+00,
      2.400000000000000355e+00,
      6.199999999999999289e+00]

# sets the x and y limits of the plot to different sizes
xlimit_sep = [3, 10, 72]
ylimit_sep = [6, 6, 10]

for i in range(len(xlimit_sep)):
    fig1, ax1 = plt.subplots()  # create graph
    ax1.scatter(x1, y1, c='blue', s=5, label='Not Resolved')  # Plots the points from the data

    bins_mag = [0.5, 1, 2, 3, 4, 5, 6]  # sets the bin sizes for the grid
    bins_sep = [0.5, 1.2, 6.0, 12, 72]

    # This is what I am currently using to make the bins and this works great
    ax1.set_yticks(bins_mag)
    ax1.set_yticks(bins_mag, minor=True)
    ax1.set_xticks(bins_sep)
    ax1.set_xticks(bins_sep, minor=True)

    ax1.grid(which='both')
    ax1.grid(which='minor', alpha=0.5)
    ax1.grid(which='major', alpha=0.5)
    # my issue is that the tick marks of the plot are no long the auto generated ones

    # sets the limits displays to the users
    plt.xlim(0, xlimit_sep[i])
    plt.ylim(0, ylimit_sep[i])

    # creates the legend
    ax1.legend(loc='center left', bbox_to_anchor=(1, 0.5))

    ax1.set_title("Resolved vs. Not Resolved")
    plt.xlabel("Separation")
    plt.ylabel("$\Delta$ m")
    plt.savefig('temp\plots' + str(i) + '.png', bbox_inches='tight')
plt.show()

输出为: A scatter plot with grid lines in the correct places and the tick marks line up with the grid lines zoom2

A scatter plot with grid lines in the correct places and the tick marks line up with the grid lines zoom1

A scatter plot with grid lines in the correct places and the tick marks line up with the grid lines zoom3

我想要的是网格线独立于 x 轴标签。当您在 matplotlib 中绘图时,默认绘图允许刻度线随着您放大和缩小而移动。我想要默认的 x_ticks,然后是自定义网格线。

这是我想要的示例: THe same plot with the grid lines but now the x-axis is red highlighting where the x-axis tick marks should be.

感谢您的宝贵时间。

您可以使用主刻度来设置刻度标签,而仅使用次刻度来设置网格。然而,一个问题是 matplotlib 在次要刻度与主要刻度重合时会抑制次要刻度。有时使用的一个技巧是向小刻度添加一些 epsilon(例如 1e-4),让 matplotlib 假设它们处于不同的位置。

另一种方法是通过 axvline and/or axhline“手动”绘制网格线。这是一些示例代码。如果你想要每条网格线的 y 刻度,你仍然可以调用 ax1.set_yticks(bins_mag)。无论如何,将次要刻度设置在与主要刻度完全相同的位置是行不通的,因为 matplotlib 会抑制每个重合的刻度。

import seaborn as sns
fmri = sns.load_dataset("fmri")
ax = sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event", style="event", markers=["o"]*2)

import matplotlib.pyplot as plt

# Sample of data being read in
x1 = [7.0, 0.4, 0.2, 10.0, 0.7, 0.7, 1.3, 0.2, 11.3, 0.2, 0.4, 4.1, 7.9, 0.3, 4.0]
y1 = [6.6, 5.4, 1.51, -0.3, 5.5, 1.76, 5.5, 0.23, 3.38, 2.28, 4.91, 3.85, 5.5, 2.4, 6.2]

# sets the x and y limits of the plot to different sizes
xlimit_sep = [3, 10, 72]
ylimit_sep = [6, 6, 10]

for i in range(len(xlimit_sep)):
     fig1, ax1 = plt.subplots()
     ax1.scatter(x1, y1, c='blue', s=5, label='Not Resolved')

     bins_mag = [0.5, 1, 2, 3, 4, 5, 6]  # sets the bin sizes for the grid
     bins_sep = [0.5, 1.2, 6.0, 12, 72]

     for mag in bins_mag:
          ax1.axhline(mag, color='black', alpha=0.5)
     for sep in bins_sep:
          ax1.axvline(sep, color='black', alpha=0.5)

     # sets the limits displays to the users
     plt.xlim(0, xlimit_sep[i])
     plt.ylim(0, ylimit_sep[i])

     # creates the legend
     ax1.legend(loc='center left', bbox_to_anchor=(1, 0.5))

     ax1.set_title("Resolved vs. Not Resolved")
     plt.xlabel("Separation")
     plt.ylabel("$\Delta$ m")
     plt.savefig('temp\plots' + str(i) + '.png', bbox_inches='tight')