具有相等条宽的对数多序列图

时间:2015-05-30 21:47:22

标签: numpy matplotlib histogram

我有类似

的东西
import matplotlib.pyplot as plt
import numpy as np

a=[0.05, 0.1, 0.2, 1, 2, 3]
plt.hist((a*2, a*3), bins=[0, 0.1, 1, 10])
plt.gca().set_xscale("symlog", linthreshx=0.1)
plt.show()

给出了以下情节: log histogram

可以看出,条形宽度不相等。在线性部分(从0到0.1),一切都是找到的,但在此之后,条形宽度仍然是线性刻度,而轴是对数刻度,给出了条形和间距之间的不均匀宽度(刻度线是不在酒吧中间。)

有没有办法纠正这个?

4 个答案:

答案 0 :(得分:1)

如果您对绘制数据集一个接一个地绘制的绘图没有问题,则可以使用histtype='stepfilled'。当然,您需要仔细选择带有alpha值的颜色,这样才能看到所有数据...

a = [0.05, 0.1, 0.2, 1, 2, 3] * 2
b = [0.05, 0.05, 0.05, 0.15, 0.15, 2]
colors = [(0.2, 0.2, 0.9, 0.5), (0.9, 0.2, 0.2, 0.5)]  # RGBA tuples
plt.hist((a, b), bins=[0, 0.1, 1, 10], histtype='stepfilled', color=colors)
plt.gca().set_xscale("symlog", linthreshx=0.1)
plt.show()

为了更好的说明,我稍微更改了您的数据。这给了我: Results

由于某种原因,重叠颜色似乎出错(matplotlib 1.3.1 with Python 3.4.0;这是一个错误吗?),但它是解决问题的唯一解决方案/替代方案。

答案 1 :(得分:1)

好的,我发现了真正的问题:当您使用这些边缘设置创建直方图时,直方图会创建具有相同大小的条形图,并且在非对数刻度上创建相等的外部间距。

为了演示,这里是问题中情节的放大版本,但是以非对数比例: hist-non-log

注意前两个条形如何以(0 + 0.1)/ 2 = 0.05为中心,边缘处的间隙为0.1 / 10 = 0.01,而接下来的两个条形以(0.1 + 1.0)/ 2为中心= 0.55,任一边缘的间隙为1.1 / 10 = 0.11。

将物品转换为对数刻度时,条形宽度和边缘宽度都会造成巨大的折腾。事实上,你有一个从0到0.1的线性刻度,之后事物成为对数刻度。

我知道无法解决这个问题,除了手动完成所有事情。我已经使用了边缘的几何方法来计算条边和条宽应该是什么。请注意,这段代码仅适用于两个数据集。如果你有更多的数据集,你需要有一些函数用适当的几何系列填充bin边缘。

JobType

最终结果: final-result

抱歉,这些酒吧之间的整齐差距被杀死了。同样,这可以通过进行适当的几何插值来修复,以便在对数刻度上一切都是线性的。

答案 2 :(得分:1)

https://stackoverflow.com/a/30555229/635387的启发,我提出了以下解决方案:

import matplotlib.pyplot as plt
import numpy as np

d=[0.05, 0.1, 0.2, 1, 2, 3]


def LogHistPlot(data, bins):
    totalWidth=0.8
    colors=("b", "r", "g")
    for i, d in enumerate(data):
        heights = np.histogram(d, bins)[0]
        width=1/len(data)*totalWidth
        left=np.array(range(len(heights))) + i*width

        plt.bar(left, heights, width, color=colors[i], label=i)
        plt.xticks(range(len(bins)), bins)
    plt.legend(loc='best')

LogHistPlot((d*2, d*3, d*4), [0, 0.1, 1, 10])

plt.show()

产生这个情节: Correct logarithmic histogram with multiple datasets

基本思想是删除plt.hist函数,通过numpy计算直方图并用plt.bar绘制它。比,你可以轻松使用线性x轴,这使得条宽计算变得微不足道。最后,刻度线被箱边缘取代,产生对数刻度。而且你甚至不必处理symlog线性/对数botchery了。

答案 3 :(得分:0)

以防万一有人偶然发现了这个问题: 该解决方案看起来更像应该采用的方式

plotting a histogram on a Log scale with Matplotlib