如何删除与对数刻度轴上的自定义 xtick 对应的特定网格线? [英] How to remove a particular grid line corresponding to a custom xtick on a log scale axis?

查看:47
本文介绍了如何删除与对数刻度轴上的自定义 xtick 对应的特定网格线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想删除与自定义 xtick 对应的垂直网格线(显示在下图中的 x = 71).我可以使用 hack 删除与下图中 ytick 701 对应的水平网格线:由于我在 y 轴上没有小刻度,我定义了与指向最大值并穿过 y 的线相对应的自定义 ytick轴作为小刻度,然后我禁用了 y 轴上小刻度的网格线.不幸的是,如果不禁用小刻度的网格线,我就无法在 x 轴上使用相同的 hack,这是我想不惜一切代价避免的事情.

I'd like to remove the vertical grid line corresponding to the custom xtick (displayed at x = 71 in the below picture). I could remove a horizontal grid line corresponding to the ytick 701 in the below picture by using a hack : since I have no minor tick on the y axis, I defined the custom ytick corresponding to the line that points toward the maximum and crosses the y axis as a minor tick, and then I disabled grid lines for minor ticks on the y axis. Unfortunately I cannot use the same hack on the x axis without disabling the grid lines of the minor ticks and that's something I'd like to avoid at all costs.

下面是一个不那么小但仍然是 WE.

Below is a not so minimal albeit still WE.

很多东西我不明白,2个专业是为什么

There are many things I don't understand, the 2 majors are why does

locs, labels = plt.xticks() 

不返回绘制的位置和标签,为什么我不将xticks标签显示为10 ^ x,其中x = 0、1、2和3,但这超出了原始问题的范围.

not return the locs and labels that are plotted and why I don't get xticks labels displayed as 10^x where x = 0, 1, 2 and 3 but that's outside the scope of the original question.

import matplotlib.pyplot as plt
plt.grid(True)
import numpy as np

# Generate data
x_data = np.arange(1, 1000 , 10)
y_data = np.random.lognormal(1e-5, 3, len(x_data))
y_max = max(y_data) 

# plot
plt.xscale('log')
import math
ratio_log = math.log(x_data[np.argmax(y_data)]) / math.log(max(x_data)) # I need to do this in order to plot a horizontal red dashed line that points to the max and do not extend any further.
plt.axhline(y=y_max, xmin=0, xmax = ratio_log, color='r', linestyle='--')  # horizontal line pointing to the max y value. 
axes = plt.gca()
axes.set_xlim([1, max(x_data)]) # Limits for the x axis.

# custom ticks and labels
# First yticks because I'm able to achieve what I seek
axes.set_yticks([int(y_max)], minor=True) # Sets the custom ytick as a minor one.
from matplotlib.ticker import FormatStrFormatter
axes.yaxis.set_minor_formatter(FormatStrFormatter("%.0f"))          
axes.yaxis.grid(False, which='minor') # Removes minor yticks grid. Since I only have my custom yticks as a minor one, this will disable only the grid line corresponding to that ytick. That's a hack.         
import matplotlib.ticker as plticker
loc = plticker.MultipleLocator(base=y_max / 3.3) # this locator puts ticks at regular intervals. I ensure the y axis ticks look ok.
axes.yaxis.set_major_locator(loc)

# Now xticks. I'm having a lot of difficulty here, unable to remove the grid of a particular custom xticks.
locs, labels = plt.xticks() # Strangely, this doesn't return the locs and labels that are plotted. There are indeed 2 values that aren't displayed in the plot, here 1.00000000e-01 and 1.00000000e+04. I've got to remove them before I can append my custom loc and label.

# This means that if I do: plt.xticks(locs, labels) right here, it would enlarge both the lower and upper limits on the x axis... I fail to see how that's intuitive or useful at all. Might this be a bug?
locs = np.append(locs[1:-1], np.asarray(x_data[np.argmax(y_data)])) # One of the ugliest hack I have ever seen... to get correct ticks and labels.
labels = (str(int(loc)) for loc in locs) # Just visuals to get integers on the axis.
plt.xticks(locs, labels) # updates the xticks and labels.
plt.plot((x_data[np.argmax(y_data)], x_data[np.argmax(y_data)]), (0, y_max), 'r--') # vertical line that points to the max. Non OO way to do it, so a bad way.
plt.plot(x_data, y_data)
plt.savefig('grid_prob.png')
plt.close()

下面的示例图片(代码每次执行输出不同的图片,但问题出现在所有图片中).

Example picture below (the code outputs a different picture each time it is executed, but the problem appears in all pictures).

推荐答案

这个想法归功于@ImportanceOfBeingErnest,我非常感谢他.

Credit for the idea goes to @ImportanceOfBeingErnest to whom I am extremely grateful.

我用

axes.xaxis.grid(False, which='both')

,然后我添加了一个对应于每个 xtick 的网格,除了带有以下循环的自定义网格:

, then I added a grid correspond to each xtick except the custom one with the following loop:

for loc in locs[1:-1]:
    if loc != x_data[np.argmax(y_data)]:
        plt.axvline(x=loc, color = 'grey', linestyle = '-', linewidth = 0.4)                                                                                                            

在该行之前插入此代码

plt.xticks(locs, labels) # updates the xticks and labels.  

下面的输出图片示例.

这篇关于如何删除与对数刻度轴上的自定义 xtick 对应的特定网格线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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