更改 x 轴或 y 轴上的刻度频率

2024-11-27 10:43:00
admin
原创
15
摘要:问题描述:我正在尝试修复 Python 如何绘制我的数据。说:x = [0, 5, 9, 10, 15] y = [0, 1, 2, 3, 4] matplotlib.pyplot.plot(x, y) matplotlib.pyplot.show() x 轴的刻度以 5 为间隔绘制。有没有办法让它显示 1...

问题描述:

我正在尝试修复 Python 如何绘制我的数据。说:

x = [0, 5, 9, 10, 15]
y = [0, 1, 2, 3, 4]

matplotlib.pyplot.plot(x, y)
matplotlib.pyplot.show()

x 轴的刻度以 5 为间隔绘制。有没有办法让它显示 1 的间隔?


解决方案 1:

您可以明确设置您想要刻度的位置plt.xticks

plt.xticks(np.arange(min(x), max(x)+1, 1.0))

例如,

import numpy as np
import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(np.arange(min(x), max(x)+1, 1.0))
plt.show()

(为了以防万一,np.arange使用了 而不是 Python 的函数,并且是浮点数而不是整数。)range`min(x)`max(x)


plt.plot(或)函数ax.plot将自动设置默认值xy限制。如果您希望保留这些限制,而只是更改刻度标记的步长,那么您可以使用ax.get_xlim()来发现 Matplotlib 已经设置了哪些限制。

start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, stepsize))

默认的刻度格式化程序应该能够很好地将刻度值四舍五入为合理的有效数字。但是,如果您希望对格式有更多控制权,则可以定义自己的格式化程序。例如,

ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))

这是一个可运行的示例:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, 0.712123))
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
plt.show()

解决方案 2:

另一种方法是设置轴定位器:

import matplotlib.ticker as plticker

loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)

根据您的需要,有几种不同类型的定位器。

以下是完整示例:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)
plt.show()

解决方案 3:

我喜欢这个解决方案(来自Matplotlib Plotting Cookbook):

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]

tick_spacing = 1

fig, ax = plt.subplots(1,1)
ax.plot(x,y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()

该解决方案让您通过给出的数字明确控制刻度间距ticker.MultipleLocater(),允许自动限制确定,并且以后易于读取。

解决方案 4:

如果有人对通用的单行代码感兴趣,只需获取当前刻度并使用它来通过每隔一个刻度进行采样来设置新的刻度。

ax.set_xticks(ax.get_xticks()[::2])

解决方案 5:

如果您只想设置间距,则使用最少的样板简单的一行:

plt.gca().xaxis.set_major_locator(plt.MultipleLocator(1))

也适用于轻微的蜱虫:

plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))

有点拗口,但相当紧凑

解决方案 6:

这有点老套,但这是迄今为止我发现的最简洁/最容易理解的示例。它来自 SO 上的一个答案:

隐藏 matplotlib 颜色条中每个第 n 个刻度标签的最干净的方法?

for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)

然后,您可以循环设置标签,根据所需的密度将其设置为可见或不可见。

编辑:请注意,有时 matplotlib 会设置标签 == '',因此可能看起来标签不存在,但实际上它存在并且没有显示任何内容。为了确保循环遍历实际可见的标签,您可以尝试:

visible_labels = [lab for lab in ax.get_xticklabels() if lab.get_visible() is True and lab.get_text() != '']
plt.setp(visible_labels[::2], visible=False)

解决方案 7:

这是一个老话题,但我时不时会遇到这个问题,并做了这个功能。它非常方便:

import matplotlib.pyplot as pp
import numpy as np

def resadjust(ax, xres=None, yres=None):
    """
    Send in an axis and I fix the resolution as desired.
    """

    if xres:
        start, stop = ax.get_xlim()
        ticks = np.arange(start, stop + xres, xres)
        ax.set_xticks(ticks)
    if yres:
        start, stop = ax.get_ylim()
        ticks = np.arange(start, stop + yres, yres)
        ax.set_yticks(ticks)

控制刻度的一个注意事项是,在添加行之后,不再享受最大比例的交互式自动更新。然后执行

gca().set_ylim(top=new_top) # for example

并再次运行重新调整功能。

解决方案 8:

我开发了一个不太优雅的解决方案。假设我们有 X 轴以及 X 轴上每个点的标签列表。

例子:

import matplotlib.pyplot as plt

x = [0,1,2,3,4,5]
y = [10,20,15,18,7,19]
xlabels = ['jan','feb','mar','apr','may','jun']

假设我只想显示“二月”和“六月”的刻度标签

xlabelsnew = []
for i in xlabels:
    if i not in ['feb','jun']:
        i = ' '
        xlabelsnew.append(i)
    else:
        xlabelsnew.append(i)

好,现在我们有了一个假的标签列表。首先,我们绘制了原始版本。

plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()

现在,是修改后的版本。

plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabelsnew,rotation=45)
plt.show()

解决方案 9:

通用的一行程序,仅导入Numpy:

ax.set_xticks(np.arange(min(x),max(x),1))

设置在问题的上下文中:

import numpy as np
import matplotlib.pyplot as plt 
fig, ax = plt.subplots()
x = [0,5,9,10,15]
y = [0,1,2,3,4]
ax.plot(x,y)
ax.set_xticks(np.arange(min(x),max(x),1))
plt.show()

工作原理:

  1. fig, ax = plt.subplots()给出包含轴的 ax 对象。

  2. np.arange(min(x),max(x),1)给出一个从 x 的最小值到 x 的最大值的区间为 1 的数组。这就是我们想要的新的 x 刻度。

  3. ax.set_xticks()改变斧头对象上的刻度。

解决方案 10:

纯 Python 实现

下面是所需功能的纯 Python 实现,它可以处理任何具有正值、负值或混合值的数字系列(整数或浮点数),并允许用户指定所需的步长:

import math

def computeTicks (x, step = 5):
    """
    Computes domain with given step encompassing series x
    @ params
    x    - Required - A list-like object of integers or floats
    step - Optional - Tick frequency
    """
    xMax, xMin = math.ceil(max(x)), math.floor(min(x))
    dMax, dMin = xMax + abs((xMax % step) - step) + (step if (xMax % step != 0) else 0), xMin - abs((xMin % step))
    return range(dMin, dMax, step)

示例输出

# Negative to Positive
series = [-2, 18, 24, 29, 43]
print(list(computeTicks(series)))

[-5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

# Negative to 0
series = [-30, -14, -10, -9, -3, 0]
print(list(computeTicks(series)))

[-30, -25, -20, -15, -10, -5, 0]

# 0 to Positive
series = [19, 23, 24, 27]
print(list(computeTicks(series)))

[15, 20, 25, 30]

# Floats
series = [1.8, 12.0, 21.2]
print(list(computeTicks(series)))

[0, 5, 10, 15, 20, 25]

# Step – 100
series = [118.3, 293.2, 768.1]
print(list(computeTicks(series, step = 100)))

[100, 200, 300, 400, 500, 600, 700, 800]

示例用法

import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(computeTicks(x))
plt.show()

样本使用情况图

请注意,x 轴具有所有间隔 5 的整数值,而 y 轴具有不同的间隔(matplotlib默认行为,因为未指定刻度)。

解决方案 11:

xmarks=[i for i in range(1,length+1,1)]

plt.xticks(xmarks)

这对我有用

如果你想要 [1,5] (包括 1 和 5)之间的刻度,那么替换

length = 5

解决方案 12:

由于上述解决方案均不None适用于我的用例,因此我在此提供了一个使用(双关语!)的解决方案,它可以适应各种各样的场景。

下面是一个示例代码片段,它在XY轴上产生混乱的刻度。

# Note the super cluttered ticks on both X and Y axis.

# inputs
x = np.arange(1, 101)
y = x * np.log(x) 

fig = plt.figure()     # create figure
ax = fig.add_subplot(111)
ax.plot(x, y)
ax.set_xticks(x)        # set xtick values
ax.set_yticks(y)        # set ytick values

plt.show()

现在,我们用一个新图表来清理混乱,该图表在 x 轴和 y 轴上仅显示一组稀疏的值作为刻度。

# inputs
x = np.arange(1, 101)
y = x * np.log(x)

fig = plt.figure()       # create figure
ax = fig.add_subplot(111)
ax.plot(x, y)

ax.set_xticks(x)
ax.set_yticks(y)

# which values need to be shown?
# here, we show every third value from `x` and `y`
show_every = 3

sparse_xticks = [None] * x.shape[0]
sparse_xticks[::show_every] = x[::show_every]

sparse_yticks = [None] * y.shape[0]
sparse_yticks[::show_every] = y[::show_every]

ax.set_xticklabels(sparse_xticks, fontsize=6)   # set sparse xtick values
ax.set_yticklabels(sparse_yticks, fontsize=6)   # set sparse ytick values

plt.show()

根据用例,可以通过简单地更改show_every和使用它来调整上述代码,以对 X 或 Y 或两个轴进行采样刻度值。

sparse_xticks如果这个基于步长的解决方案不适合,那么也可以以不规则的间隔填充或的值sparse_yticks,如果这是需要的。

解决方案 13:

同时设置大刻度和小刻度:

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

ax = plt.axes()
ax.xaxis.set_major_locator(ticker.MultipleLocator(5)) # set BIG ticks
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) # set small ticks

x = range(0,21)
y = [4,8,3,10,6,12,5] * 3

plt.plot(x, y)
plt.show()

在此处输入图片描述

解决方案 14:

如果您需要使用旧的滴答标签更改滴答标签频率以及滴答频率,则依次使用set_xticks和会引发如下所示的 ValueError:set_xticklabels

ValueError: The number of FixedLocator locations (5), usually from 
a call to set_ticks, does not match the number of labels (3).

解决该问题的一种方法是同时设置两者。

  • 如果您有matplotlib>=3.5,那么您可以将标签传递给set_xticks(或set_yticksy 轴)作为第二个参数。

ax.set_xticks(new_ticks)
ax.set_xticklabels(new_labels)                    # <--- error

ax.set_xticks(new_ticks, new_labels)              # <--- OK
#                        ^^^^^^^^^^^  <--- pass labels here
  • 如果您有matplotlib<3.5,那么您可以使用set同时设置两者。

ax.set(xticks=new_ticks, xticklabels=new_labels)  # <---- OK

举一个具体的例子也许能更好地说明这一点。

import pandas as pd
ax = pd.Series(range(20), index=pd.date_range('2020', '2024', 20).date).plot()
ax.set_xticks(ax.get_xticks()[::2])
ax.set_xticklabels(ax.get_xticklabels()[::2]);  # <---- error

ax = pd.Series(range(20), index=pd.date_range('2020', '2024', 20).date).plot()
ax.set_xticks(ax.get_xticks()[::2],
              ax.get_xticklabels()[::2])        # <--- OK

ax = pd.Series(range(20), index=pd.date_range('2020', '2024', 20).date).plot()
ax.set(xticks=ax.get_xticks()[::2], 
       xticklabels=ax.get_xticklabels()[::2]);  # <---- OK

结果


对于这种特定情况,matplotlib.dates.YearLocatormatplotlib.dates.DateFormatter更灵活(例如ax.xaxis.set_major_locator(matplotlib.dates.YearLocator()))并且可能是设置刻度标签的首选方式,但上述帖子提供了针对常见错误的快速修复方法。

解决方案 15:

您可以循环浏览标签并显示或隐藏您想要的标签:

   for i, label in enumerate(ax.get_xticklabels()):
        if i % interval != 0:
            label.set_visible(False)
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   657  
  如何借鉴华为IPD体系优化企业研发?在当今竞争激烈的市场环境中,企业要想保持技术领先和产品竞争力,必须拥有一套高效且严谨的研发管理体系。华为作为全球领先的ICT解决方案提供商,其集成产品开发(IPD, Integrated Product Development)体系与质量管理体系(如ISO 9000系列)的融合实践,...
IPD项目管理   15  
  IPD流程图的7种经典绘制方法详解在产品开发领域,集成产品开发(Integrated Product Development,简称IPD)流程被广泛应用,以提高产品开发的效率和质量。IPD流程图作为这一流程的可视化工具,其绘制方法至关重要。本文将详细介绍七种经典的IPD流程图绘制方法,帮助项目管理人员和团队更好地理解和...
IPD研发管理体系   18  
  IPD流程:企业创新管理的核心引擎在当今快速变化的市场环境中,企业要想持续保持竞争力,就必须不断进行创新。而IPD(Integrated Product Development,集成产品开发)流程作为一种先进的产品开发管理模式,正逐渐成为众多企业提升创新能力、加速产品上市速度、降低开发成本的重要选择。本文将深入探讨IP...
IPD管理   18  
  IPD流程与传统产品开发流程的概述在产品开发领域,企业不断寻求高效、系统的管理方法以确保产品能够顺利从概念转化为市场成功的产品。集成产品开发(Integrated Product Development,简称IPD)流程与传统产品开发流程是两种截然不同的管理理念和方法。传统产品开发流程往往以职能部门为核心,各部门按顺序...
IPD流程中PDCP是什么意思   16  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用