【问题标题】:How to create a bar plot with a logarithmic x-axis and gaps between the bars?如何创建具有对数 x 轴和条形之间间隙的条形图?
【发布时间】:2021-11-09 23:02:17
【问题描述】:

我想使用脚本中提到的数据绘制一个漂亮的条形图。此外,x 轴应该是对数的,并且条形之间必须有间隙。

我尝试了如下脚本:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

fig = plt.figure()

x = [0.000001,0.00001,0.0001,0.001,0.01,0.1,1.0]
height = [5.3,1.8,8.24,5.8,2.8,3.3,4.2]
width = 0.000001

plt.bar(x, height, width, color='b' )
plt.xscale("log")  
plt.savefig('SimpleBar.png')
plt.show()

但是,x 轴值未按预期绘制。

【问题讨论】:

    标签: python pandas numpy matplotlib


    【解决方案1】:

    使用对数刻度 x 轴,您无法为条形设置恒定宽度。例如。第一个条将介于00.000002 之间(0 在对数刻度上处于负无穷大)。

    您可以将 x 位置用于条形的左边缘,将下一个 x 位置用于右边缘:

    import matplotlib.pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    x = [0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1.0]
    height = [5.3, 1.8, 8.24, 5.8, 2.8, 3.3, 4.2]
    
    plt.xscale("log")
    widths = np.diff(x + [x[-1] * 10])
    plt.bar(x, height, widths, align='edge', facecolor='dodgerblue', edgecolor='white', lw=2)
    plt.show()
    

    如果要将条形“居中”在原始 x 值周围,则需要计算每个条形在对数空间中的开始和结束位置。获得更多条间距的最简单方法是设置更厚的白色边框。

    import matplotlib.pyplot as plt
    import numpy as np
    
    x = [0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1.0]
    height = [5.3, 1.8, 8.24, 5.8, 2.8, 3.3, 4.2]
    
    plt.xscale("log")
    padded_x = [x[0] / 10] + x + [x[-1] * 10]
    centers = [np.sqrt(x0 * x1) for x0, x1 in zip(padded_x[:-1], padded_x[1:])]
    widths = np.diff(centers)
    plt.bar(centers[:-1], height, widths, align='edge', facecolor='dodgerblue', edgecolor='white', lw=4)
    plt.margins(x=0.01)
    plt.show()
    

    如果您计算每个条的新左右位置,您还可以有一个可配置的宽度:

    import matplotlib.pyplot as plt
    import numpy as np
    
    x = [0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1.0]
    height = [5.3, 1.8, 8.24, 5.8, 2.8, 3.3, 4.2]
    
    plt.xscale("log")
    padded_x = [x[0] / 10] + x + [x[-1] * 10]
    width = 0.3  # 1 for full width, closer to 0 for thinner bars
    lefts = [x1 ** (1 - width / 2) * x0 ** (width / 2) for x0, x1 in zip(padded_x[:-2], padded_x[1:-1])]
    rights = [x0 ** (1 - width / 2) * x1 ** (width / 2) for x0, x1 in zip(padded_x[1:-1], padded_x[2:])]
    widths = [r - l for l, r in zip(lefts, rights)]
    plt.bar(lefts, height, widths, align='edge', facecolor='dodgerblue', lw=0)
    plt.show()
    

    【讨论】:

    • 如何改变 te bar 的宽度...有什么建议吗??
    • 另外,x 轴的值并不直接在条形的正下方小位移
    • 我们不能改变宽度吗,我需要小细条
    • 好的谢谢,如果我不想在 x 轴上使用日志,这个脚本可以工作吗
    • 它可以在没有对数刻度的情况下工作,但右侧的条将非常宽,而左侧的条非常细。
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 2011-10-02
    相关资源
    最近更新 更多