我有类似
的东西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()
给出了以下情节:
可以看出,条形宽度不相等。在线性部分(从0到0.1),一切都是找到的,但在此之后,条形宽度仍然是线性刻度,而轴是对数刻度,给出了条形和间距之间的不均匀宽度(刻度线是不在酒吧中间。)
有没有办法纠正这个?
答案 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()
为了更好的说明,我稍微更改了您的数据。这给了我:
由于某种原因,重叠颜色似乎出错(matplotlib 1.3.1 with Python 3.4.0;这是一个错误吗?),但它是解决问题的唯一解决方案/替代方案。
答案 1 :(得分:1)
好的,我发现了真正的问题:当您使用这些边缘设置创建直方图时,直方图会创建具有相同大小的条形图,并且在非对数刻度上创建相等的外部间距。
为了演示,这里是问题中情节的放大版本,但是以非对数比例:
注意前两个条形如何以(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
最终结果:
抱歉,这些酒吧之间的整齐差距被杀死了。同样,这可以通过进行适当的几何插值来修复,以便在对数刻度上一切都是线性的。
答案 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()
产生这个情节:
基本思想是删除plt.hist函数,通过numpy计算直方图并用plt.bar绘制它。比,你可以轻松使用线性x轴,这使得条宽计算变得微不足道。最后,刻度线被箱边缘取代,产生对数刻度。而且你甚至不必处理symlog线性/对数botchery了。
答案 3 :(得分:0)
以防万一有人偶然发现了这个问题: 该解决方案看起来更像应该采用的方式