【问题标题】:matplotlib - How to plot a graph with uneven intervals of 2^n?matplotlib - 如何绘制不均匀间隔为 2^n 的图形?
【发布时间】:2018-02-26 09:52:05
【问题描述】:

我有 2 个列表,每个列表有 128 个元素

x = [1,2,3,...,128]
y = [y1,y2,...,y128]

我应该如何使用 matplotlib 绘制 (x,y),其中 x 轴出现在这个 screenshot 中?

为了复制图表,我 (1) 从原始列表中创建了 2 个额外的列表,并且 (2) 使用了 set_xticklabels:

f, ax1 = plt.subplots(1,1,figsize=(16,7))  
x1 = [1, 2, 4, 8, 16, 32, 64, 128]  
y1 = [y[0],y[1],y[3],y[7],y[15],y[31],y[63],y[127]]  

line1 = ax1.plot(x1,y1,label="Performance",color='b',linestyle="-")  

ax1.set_xticklabels([0,1,2,4,8,16,32,64,128])  
ax1.set_xlabel('Time Period',fontsize=15)  
ax1.set_ylabel("Value",color='b',fontsize=15)

这种方法的问题是只绘制了 8 对值,而省略了 120 对。

【问题讨论】:

  • 你试过xticksyticks吗?
  • 你用来获取这张图片的代码是什么?使用plt.plot(x, f(x)) 之类的函数还不够吗?
  • @IMCoins 使用 plt.plot(x, f(x)) 是不够的,因为我的 x 轴的间隔是不均匀的。我知道如何在我的图表上显示 8 个点,但我要的是如何显示 128 个数据点,同时仍然具有所附屏幕截图所示的 x 轴。

标签: python matplotlib axis


【解决方案1】:

如果我的 cmets 不够清楚,请询问。 :)

from matplotlib import pyplot as plt

#   Instanciating my lists...
f = lambda x:x**2
x = [nb for nb in range(1, 129)]
y = [f(nb) for nb in x]

#   New values you want to plot, with linear spacing.
indexes_to_keep = [1, 2, 4, 8, 16, 32, 64, 128]
y_to_use = [y[nb - 1] for nb in indexes_to_keep]

#   First plot that shows the 128 points as a whole.
fig = plt.figure(figsize=(10, 5.4))
ax1 = fig.add_subplot(121)
ax1.plot(x, y)
ax1.set_title('Former values')

#   Second plot that shows only the indexes you wish to keep.
ax2 = fig.add_subplot(122)

#   my_ticks = [1, 2, 3, 4, 5, 6, 7]
#   meaning : my_ticks will be linear values.
my_ticks = [i for i in range(len(indexes_to_keep))]

#   We set the ticks we want to show, meaning : all our list
#   instead of some linear spacing matplotlib will show by default
ax2.set_xticks(my_ticks)

#   Then, we manually change the name of the X ticks.
ax2.set_xticklabels(indexes_to_keep)

#   We will then, plot the LINEAR x axis,
#   but with respect to the y-axis values pre-processed.
ax2.plot(my_ticks, y_to_use)
ax2.set_title('New selected values with linear spacing')

plt.show()

显示...

【讨论】:

  • 我有类似的需求,我的 x 轴项目是 datetime 对象。在这个问题中,我的日期没有定期分开。首先我是这样做的:plt.bar(hours, frequency) 其中hoursdatetime 对象的列表,这是在绘制像左图这样的值,保持x 刻度在固定间隔。由于这种规则间距,大多数 y 值都是 0。我只是将 x 轴项更改为字符串:plt.bar([h.isoformat() for h in hours], frequency) 然后它只将那些日期作为列表中存在的刻度,而不是做任何常规间距。这解决了我的问题。
【解决方案2】:

您正在寻找的是以 2 为底的对数刻度。matplotlib 提供对数刻度,您可以定义任何您想要的底数:

from matplotlib import pyplot as plt
from matplotlib.ticker import ScalarFormatter
#sample data
x = list(range(1, 130))
y = list(range(3, 260, 2)) 

f, ax1 = plt.subplots(1,1,figsize=(16,7))
x1 = [  1,   2,   4,   8,   16,   32,   64,   128]
y1 = [y[0],y[1],y[3],y[7],y[15],y[31],y[63],y[127]]
#just the points, where the ticks are
ax1.plot(x1, y1,"bo-", label = "Performance")
#all other points to contrast this
ax1.plot(x, [270 - i for i in y], "rx-", label = "anti-Performance")
#transform x axis into logarithmic scale with base 2
plt.xscale("log", basex = 2)
#modify x axis ticks from exponential representation to float 
ax1.get_xaxis().set_major_formatter(ScalarFormatter())
ax1.set_xlabel('Time Period',fontsize=15)
ax1.set_ylabel("Value",color='b',fontsize=15)
plt.legend()
plt.show()

输出:

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    相关资源
    最近更新 更多