我希望每天使用Python制作动态情节。
轴的X轴为12个月,过程将是Matplotlib中的一个barh,代码如下:
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()
但是在情节之后,xtick显示7月是100%,这不是我想要的。
我搜索了matplotlib的文档,但没有找到答案:(。我怎样才能使x轴刻度显示1月 - 12月,而barh显示年份的百分比?
答案 0 :(得分:4)
如何在Python matplotlib中使xtick与xlim不同?
这是不可能的。 xtick
基本上是xlim
(您的x范围)内的子域。 "蜱"只不过是你所选择的Locator
产生的极限范围内的离散点。在视觉上,刻度线以两种方式呈现给你:第一,小正交线,我认为它给出了" tick"它的名字,第二个,显示在它附近的值。但是,如何将值呈现给用户又取决于所选择的Formatter
。设置自定义标签归结为使用FixedFormatter
,它只返回本地刻度线索引的任意标签。
有关详细信息,请参阅https://matplotlib.org/api/ticker_api.html。
您的代码出了什么问题?
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.])
设置限制如何生成 6 刻度:
如果您现在指定更多自定义标签而不是实际的刻度数,则会忽略过多的自定义标签。这是您遇到的行为。
有趣的是。如果您之后设置自定义标签并增加刻度数(以及范围),会发生什么?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)
它会增加你的x范围(!)并且只显示超过12个刻度的标签:
请注意,您还在设置标签后明确更改了x范围。但是因为底层的Formatter并不真正关心具体的值,而是本地的滴答索引和新的x-range有相同数量的滴答,你无法真正看到发生了什么。设置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才能获得所需的宽度。
全部放在一起:
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()
设置条形宽度时,如果同时删除类型转换为int
,则会收到以下结果:
P.S。原谅我" Okt"而不是" 10月"。那是我的德国灵魂在工作.. :))
答案 1 :(得分:0)
当然,更简单的方法是在轴上创建数月的图表。
在这里,问题是matplotlib不知道在哪个位置绘制字符串" 2月"。因此,从标签开始,您还需要设置xtick位置。 这可以完成,例如使用
ax.set_xticks(numpy.linspace(0,365,13)/365.*100)
我们使用numpy。您也可以手动输入与月份相对应的天数,并获得更准确的结果,因为并非所有月份都具有相同的天数。
另一个问题是你在列表中忘了带十月。 : - )
完整代码:
import datetime
import matplotlib.pyplot as plt
import numpy as np
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','Oct', 'Nov', 'Dec']
ax.set_xticks(np.linspace(0,365,13)/365.*100)
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()