Matplotlib:自定义 Y 轴刻度频率为每 2 或 5 次

问题描述 投票:0回答:1

亲爱的 Stackoverflow 社区 我有这个情节的输出。

  1. 我想要做的是将水平线的刻度设置为0。
  2. (更重要)将左右(Y 轴)显示的值的频率设置得更整齐。我成功地用下一个代码获得了 -50 到 30 之间的每个值。
        def round_down(value, base=5):
        return base * np.floor(value / base)
    
    def round_up(value, base=5):
        return base * np.ceil(value / base)
    
    # alligning ticks
    ax1.set_ylim(bottom=0)
    ax2.set_ylim(bottom=round_down(min(plot_data.VAR3), 10) ,top=round_up(max(plot_data.VAR3), 10))

但是我不知道如何让它在左 Y 轴上每 2 或 5 个频率发生一次。

enter image description here

这是完整代码


fig, ax1 = plt.subplots(figsize=(8, 6))

# Create a twin Axes sharing the xaxis
ax2 = ax1.twinx() # Making a twin of a first axis

lns1 = [ax1.bar(plot_data.date, plot_data.VAR2,  color= 'yellow', label="VAR2 Ratio", width= 50)] #Plotting a barplot on left axis
lns2= ax2.plot(plot_data.date, plot_data.VAR1, 'blue', label = "VAR1  (RHS)") #Plotting a line on rigth axis
lns3 = ax2.plot(plot_data.date, plot_data.VAR3, 'red',label= "VAR3 (RHS)") #Plotting again a line on right axis


lns = lns1+lns2+lns3 # Getting all together
labs = [l.get_label() for l in lns] # Getting the names of lables
ax1.legend(lns, labs, loc='upper center', bbox_to_anchor=(0.5,-0.2), #Location of label
          fancybox=False, shadow=False, ncol=5,frameon= False) #Frameon if you want to eliminate the frames
# ax1.set_xticklabels(labs, fontsize=6) #font size for the X values

def round_down(value, base=5):
    return base * np.floor(value / base)

def round_up(value, base=5):
    return base * np.ceil(value / base)

# alligning ticks
ax1.set_ylim(bottom=0)
ax2.set_ylim(bottom=round_down(min(plot_data.VAR3), 10) , top= round_up(max(plot_data.VAR3), 10))

ax2.axhline(y=0, color='black', linewidth=1, linestyle='--')



# 5 ticks from each side to have alliggned 
ax1.yaxis.set_major_locator(mtick.LinearLocator(5))
ax2.yaxis.set_major_locator(mtick.LinearLocator(5))

# To add a percentage to tick
formatter = ticker.PercentFormatter(xmax=100, decimals=0)

# Set setting Y axis ticks
ax1.yaxis.set_major_formatter(formatter)
ax2.yaxis.set_major_formatter(formatter)

# setting the frames of a viz
ax1.spines['top'].set_visible(False)
ax2.spines['top'].set_visible(False)



# FontSize of tick
ax1.tick_params(axis='x', labelsize=8, rotation=45) # Rotating ticks horizontally

start_date = plot_data.date.min()
ax1.set_xlim([start_date-1, plot_data.date.max()])
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%b %y')) #Setting the format of ticks to MM YY
ax1.xaxis.set_major_locator(mdates.MonthLocator(interval=3)) #Setting the frequency of ticks

ax1.grid(axis='y',  color='grey', linestyle='-', linewidth=0.25, zorder=0)

plt.subplots_adjust(bottom=0.2)

plt.show()

python matplotlib
1个回答
0
投票

我为你做了一个小例子,其中有 x、y1 和 y2:

x = np.linspace(1, 100, 10)
y1 = 50*np.exp(-x/10) + 5
y2 = 10*np.exp(x/100)

我执行了以下函数,该函数接受变量并为其生成刻度和标签:

def getTicksAndLabels(y, spacing = 5):
    minVal = np.floor(min(y) / spacing) * spacing # get suitable limit in min
    maxVal = np.ceil(max(y) / spacing) * spacing # get suitable limit in max
    ticks = np.arange(minVal, maxVal + 1, spacing) # define the ticks you want to set
    # maybe loop is not the best idea? don't know
    labels = [str(int(tick)) for tick in ticks] # generate labels as string
    return ticks, labels

所以绘图看起来像这样:

plt.figure()
plt.plot(x,y1, "-o")
plt.yticks(*getTicksAndLabels(y1, 2))
plt.ylabel("y1 = 50*np.exp(-x/10) + 5")
plt.twinx()
plt.plot(x,y2, "r-s")
plt.yticks(*getTicksAndLabels(y2, 5))
plt.grid()
plt.ylabel("y2 = 10*np.exp(x/100)")
plt.xlabel("x")

结果:

plotting

左侧每隔 2 间隔,右侧每隔 5 间隔。如果将正确的内容传递给函数,则会自动生成刻度。希望这有帮助。

进口:

import numpy as np
%matplotlib notebook
import matplotlib.pyplot as plt
© www.soinside.com 2019 - 2024. All rights reserved.