Python 代表范围的条形图

Python Barplot to represent Ranges

我想在 python 中制作一个分类图来表示几个变量的范围。我想也许我会使用条形图并为条形设置范围。这是我的条形图

import matplotlib.pyplot as plt
import numpy as np

data = {'a':.3, 'b': .3, 'c': .3, 'd': .1,'e':.1,'f':.1}

names = list(data.keys())    
values = list(data.values())

plt.bar(names,values)
plt.show()

根据给定代码生成的条形图: 请告诉我如何将条形的值设置为 range(.3,.4) 之类的值。换句话说,我希望条形图从(.3 到 .4 代表一个范围)而不是(0 到 .3 当前的方式)。

我知道使用条形图来表示范围很奇怪,如果有人有其他方法可以做到这一点,请添加您的代码。我真的不在乎,只要我得到一个代表至少 6 个变量范围的图,我可以在其中轻松地手动更改范围的值。

一种方法是使用 LineCollection 并将线宽设置为类似于条形图。

要使用 LineCollection,您需要提供一组 x 值来绘制 data 中提供的每个范围。为了创建与您的范围关联的 y 值,我使用了 np.arange。由于 np.arange 只能计算整数,所以我将 data 中的每个值乘以 10,然后将结果除以 10 得到输入数据。

data = {'a':(.3,.4), 'b': (.3,.4), 'c': (.3,.4), 'd': (0,.1),'e':(0,.1),'f':(0,.1)}

names = list(data.keys())    
values = list(data.values())

values = [np.arange(a[0]*10, (a[1]+0.1)*10,1)/10 for a in values]
xs = [np.ones(a.shape) for a in values]

xs = [i*a for i,a in zip(range(len(xs)), xs)]

verts = []
for x,y in zip(xs, values):
    verts.append(list(zip(x.tolist(), y.tolist())))

lc = LineCollection(verts, linewidths=40)

fig,ax = plt.subplots()
ax.add_collection(lc)
ax.set_xlim(-0.5,len(values) )
plt.xticks(np.arange(len(values)), names)

更新答案

要解决 axvline 的问题,必须考虑宽度(像素)与范围的比率。我觉得这是一个hack。

因此,这里有一个使用axvspan.

的解决方案
import numpy as np
from matplotlib import pyplot as plt

data = {'a':(0,.3), 'b': (0.2,.3), 'c': (.1,.3), 'd': (0.3,0.4),'e':(.1,.2),'f':(.1,.4)}

width = 0.5 # adjust to your liking

fig, ax = plt.subplots()

for i, values in enumerate(data.values()):

    ymin, ymax = values

    ax.axvspan(xmin=i-width/2, xmax=i+width/2, ymin=ymin,ymax=ymax)

# to illustrate that ranges are properly drawn
ax.grid(True)

#add ticks 
ax.set_xticks(np.arange(0,len(data)))    
ax.set_xticklabels(data.keys())

输出:

原回答

另一种选择是使用 axvline:

from matplotlib import pyplot as plt

data = {'a':(0,.3), 'b': (0.2,.3), 'c': (.1,.3), 'd': (0.3,0.4),'e':(.1,.2),'f':(.1,.4)}

for key, values in data.items():
    ymin, ymax = values
    plt.axvline(x=key, ymin=ymin, ymax=ymax, lw=5)

输出:

如果需要,您可以通过调整 lw 来绘制条形图。