pyplot - 如何在x轴上设置特定范围

时间:2017-01-10 01:33:05

标签: python matplotlib plot axis seaborn

我有一张CDF图,其中包含以MB为单位的wifi使用情况。为了更好地理解,我想提出以KB开头并以TB结束的用法。我想知道如何设置x轴的特定范围来替换plt.plot()的产品,并将轴x显示为[1KB 10KB 1MB 10MB 1TB 10TB],甚至是不代表的箱之间的空间真正的价值观。

enter image description here

我现在的代码

wifi = np.sort(matrix[matrix['wifi_total_mb']>0]['wifi_total_mb'].values)

g = sns.distplot(wifi, kde_kws=dict(cumulative=True))
plt.show()

由于

编辑1

我知道我可以使用plt.xticks,我已经尝试过了:plt.xticks([0.00098, 0.00977, 1, 10, 1024, 10240, 1048576, 10485760, 24117248])。这些是以MB为单位的值,表示我之前指定的样本范围。但情节仍然是错误的。

enter image description here

预期结果

在excel中,很容易实现我想要的东西。看看图像,我得到了我想要的情节,范围相同。

enter image description here

由于

1 个答案:

答案 0 :(得分:3)

计算要手动绘制的数据可能更好,而不是依赖于某些seaborn辅助函数,如distplot。这也使得更容易理解具有非常不相等的箱尺寸的直方图的基本问题。

计算直方图

可以使用np.histogram()计算数据的直方图。它可以将所需的箱子作为参数 为了获得累积直方图,np.cumsum完成了这项工作。

现在有两个选项:(a)绘制真实数据或(b)绘制bin枚举的数据。

(a)绘制实际数据:

由于bin大小非常不相等,因此对数缩放似乎已足够,可以通过semilogx(x,y)来完成。 bin边缘可以使用set_xticks显示为xticks(并且由于semilogx图不会自动正确设置标签,我们还需要将它们设置为bin边缘的值)。

(b)绘制bin枚举的数据:

第二个选项是逐个绘制直方图值,而不依赖于实际的容器大小。是非常接近问题的Excel解决方案。在这种情况下,绘图的x值只是从0到bin数的值,而xticklabels是bin边缘。

以下是完整的代码:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

#use the bin from the question
bins = [0, 0.00098, 0.00977, 1, 10, 1024, 10240, 1048576, 10485760, 24117248]

# invent some data
data = np.random.lognormal(2,4,10000)
# calculate histogram of the data into the given bins
hist, _bins = np.histogram(data, bins=bins)
# make histogram cumulative
cum_hist=np.cumsum(hist)
# normalize data to 1
norm_cum_hist = cum_hist/float(cum_hist.max())

fig, (ax, ax2) = plt.subplots(nrows=2)
plt.subplots_adjust(hspace=0.5, bottom=0.17)

# First option plots the actual data, i.e. the bin width is reflected
#   by the spacing between values on x-axis.
ax.set_title("Plotting actual data")
ax.semilogx(bins[1:],norm_cum_hist, marker="s")
ax.set_xticks(bins[1:])
ax.set_xticklabels(bins[1:] ,rotation=45, horizontalalignment="right")   

# Second option plots the data bin by bin, i.e. every bin has the same width,
#   independent of it's actual value. 
ax2.set_title("Plotting bin by bin")
ax2.plot(range(len(bins[1:])),norm_cum_hist, marker="s")
ax2.set_xticks(range(len(bins[1:])))
ax2.set_xticklabels(bins[1:] ,rotation=45, horizontalalignment="right")  

for axes in [ax, ax2]:
    axes.set_ylim([0,1.05])

plt.show()

enter image description here