如何使xtick与Python matplotlib中的xlim不同? [英] How can I make xtick different from xlim in Python matplotlib?

查看:34
本文介绍了如何使xtick与Python matplotlib中的xlim不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Python逐年绘制动态图.

轴的X轴为12个月,过程在Matplotlib中为barh,代码如下:

 导入随机导入日期时间导入matplotlib.pyplot作为pltdef get_percent():今天= datetime.date.today()开始 = 日期时间.日期(今天.年, 1, 1)差异 = 今天 - 开始百分比=差异天数/365.0回报率无花果= plt.figure(figsize =(8,2))斧= fig.add_subplot(1,1,1)百分比= get_percent()ax.axis([0,12,0,1])月份 = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug','Sep', 'Nov', 'Dec']ax.set_xticklabels(月)ax.set_xlim(0, 100)ax.barh(bottom=0.5,width=int(percent*100),height=0.2)plt.show()plt.close()

但是在情节之后,xtick 显示 7 月是一年中的 100%,这不是我想要的.

我搜索了matplotlib的文档,但没有找到答案:(.如何使x轴刻度线显示Jan-Dec,而barh显示年份百分比?

解决方案

如何使 xtick 与 Python matplotlib 中的 xlim 不同?

那是不可能的.xtick 本质上是您的 xlim(您的 x 范围)内的一个子域.提示"只不过是您选择的

如果您现在分配的自定义标签比实际的壁虱数量多更多,多余的壁虱将被忽略.这是您所经历的行为.

有趣的事情.如果您随后设置自定义标签并增加刻度线数量(以及刻度线数量),会发生什么情况?

fig = plt.figure(figsize=(8,2))斧= fig.add_subplot(1,1,1)ax.axis([0, 12, 0, 1])ax.set_xticklabels(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep','Oct', 'Nov', '十二月'])ax.set_xticks(range(24)) # [0, 1, ..., 22, 23]ax.get_xlim()# 返回 (0.0, 23.0)

它会增加您的 x 范围 (!),并且不会显示超过 12 个刻度的标签:

请注意,您还可以在设置标签后显式更改x范围.但是,由于底层的Formatter并不真正在乎具体的值,而是本地的刻度索引和新的x范围具有相同的刻度数,因此您无法真正看到正在发生的情况.设置 xlim(0, 100) 后,您的刻度实际上是 [0, 20, 40, ... 100] 而不是 [0 ... 12] 了.这很容易导致错误,这就是为什么您应该始终尝试在一个域中始终如一地操作(0-12 个月,0-100/0-1 的百分比).

<小时>

解决问题:选择域!

在此示例中,我选择月份作为我们的域,这意味着我们在0到12之间进行操作.请注意,下限0对应于1月1日,上限12对应于12月31日..我们现在可以左对齐我们的每月刻度(等于 ax.set_xticks(range(12)))或将它们放在各自的月份下(等于 import numpy as np; ax.set_xticks(np.arange(0, 12, 1) + 0.5)).当我们将限制设置为(0,12)时,修改刻度不会更改限制.

使用月份作为域还意味着您的百分比值 (0, 1) 是相对于 (0, 12) 而不是 (0, 100).因此,您必须将其乘以 12 才能获得所需的宽度.

将它们放在一起:

 导入随机导入日期时间导入matplotlib.pyplot作为pltdef get_percent():今天 = datetime.date.today()开始= datetime.date(today.year,1,1)diff =今天-开始百分比=差异天数/365.0回报率fig = plt.figure(figsize=(8,2))斧= fig.add_subplot(1,1,1)百分比 = get_percent()ax.axis([0,12,0,1])月份 = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']ax.set_xticks(range(12)) # 在 [0, 1, ..., 11] 上放置刻度ax.set_xticklabels(月)ax.barh(bottom=0.5,width=int(percent*12),height=0.2)plt.show()plt.close()

如果您在设置条宽时还删除了对 int 的类型转换,您会收到以下结果:

附言请原谅我使用Okt"而不是Oct".那是我在工作中的德国灵魂..:)

I want to make a dynamic plot every day for year process with Python.

The X axis of the axes will be 12 month, and the process will be a barh in Matplotlib, as code below:

import random
import datetime
import matplotlib.pyplot as plt

def get_percent():
    today = datetime.date.today()
    start = datetime.date(today.year, 1, 1)
    diff = today - start
    percent = diff.days/365.0
    return percent

fig = plt.figure(figsize=(8,2))
ax = fig.add_subplot(1,1,1)
percent = get_percent()

ax.axis([0, 12, 0, 1])
month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug','Sep', 'Nov', 'Dec']
ax.set_xticklabels(month)
ax.set_xlim(0, 100)
ax.barh(bottom=0.5,width=int(percent*100),height=0.2)

plt.show()
plt.close()

But after plot, the xtick show july to be 100% of the year, which is not I want.

I searched the doc of matplotlib, but did not find the answer :(. How can I make the x axis tick show Jan - Dec, and the barh show the percentage of the year?

解决方案

How can I make xtick different from xlim in Python matplotlib?

That is not possible. xtick is essentially a sub-domain within your xlim (your x-range). "Ticks" are nothing more than discrete points within your limits which are produced by your chosen Locator. Visually, the tick presents itself to you in two ways: First, the little orthogonal line, which I presume gives the "tick" its name, and second, the value which is shown close to it. However, how the value is presented to the user is, in turn, determined by the chosen Formatter. Setting custom labels comes down to using a FixedFormatter which simply returns arbitrary labels for local tick indices.

See https://matplotlib.org/api/ticker_api.html for further details.


What goes wrong in your code?

fig = plt.figure(figsize=(8,2))
ax = fig.add_subplot(1,1,1)
ax.axis([0, 12, 0, 1])
ax.get_xticks()
# returns array([  0.,   2.,   4.,   6.,   8.,  10.,  12.])

Settings the limits how you do it produces exactly 6 ticks:

If you now assign more custom labels than the actual number of ticks, the excessive ones are simply ignored. This is the behavior you experienced.

Funny thing. What happens if you set the custom labels and increase the number of ticks (and by that also the range) afterwards?

fig = plt.figure(figsize=(8,2))
ax = fig.add_subplot(1,1,1)
ax.axis([0, 12, 0, 1])
ax.set_xticklabels(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep','Oct', 'Nov', 'Dec'])
ax.set_xticks(range(24))  # [0, 1, ..., 22, 23]
ax.get_xlim()
# returns (0.0, 23.0)

It increases your x-range (!) and simply shows no labels for the exceeding 12 ticks:

Note that you also changed the x-range explicitly after setting the labels. But because the underlying Formatter does not really care about the concrete values but rather the local tick index AND the new x-range had the same amount of ticks you could not really see what is going on. After setting xlim(0, 100) your ticks actually were [0, 20, 40, ... 100] and not [0 ... 12] anymore. This can easily cause bugs and that is why you should always try to operate consistently in one domain (months 0-12, percent 0-100/0-1).


Solving the problem: Choosing a domain!

For the sake of this example I choose the months as our domain which means we operate in the range 0 to 12. Note that 0, the lower bound, corresponds to January 1st and 12, the upper bound, corresponds to December 31st. We can now left-align our monthly ticks (equals ax.set_xticks(range(12))) or center them under the respective month (equals import numpy as np; ax.set_xticks(np.arange(0, 12, 1) + 0.5)). As we set the limits to be (0, 12) modifying the ticks will not change the limits.

Using months as the domain also implies that your percent value (0, 1) is relative to (0, 12) and not (0, 100). Consequently, you have to multiply it by 12 to obtain the width you desire.

Putting it all together:

import random
import datetime
import matplotlib.pyplot as plt

def get_percent():
    today = datetime.date.today()
    start = datetime.date(today.year, 1, 1)
    diff = today - start
    percent = diff.days/365.0
    return percent

fig = plt.figure(figsize=(8,2))
ax = fig.add_subplot(1,1,1)
percent = get_percent()

ax.axis([0, 12, 0, 1])
month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
ax.set_xticks(range(12))  # ticks placed on [0, 1, ..., 11]
ax.set_xticklabels(month)
ax.barh(bottom=0.5,width=int(percent*12),height=0.2)

plt.show()
plt.close()

When you also remove the typecast to int when setting your bar width you receive the following result:

P.S. Forgive me for "Okt" instead of "Oct". That was my German soul at work.. :)

这篇关于如何使xtick与Python matplotlib中的xlim不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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