首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用matplotlib设置基线并让条形图的条形图向下增长

如何使用matplotlib设置基线并让条形图的条形图向下增长
EN

Stack Overflow用户
提问于 2014-02-20 16:53:39
回答 2查看 4.4K关注 0票数 2

我有一些我想用mathplotlib绘制的数据。例如,我有一个基准值的测量值,我想将它与一个参考值进行比较。我计算一个“减速因子”来表示一个比另一个慢多少,比如说,浏览器比另一个慢多少。

到目前为止,它看起来几乎是这样的:

情节的代码是:

代码语言:javascript
复制
#!/usr/bin/env python
import numpy as np
# Import Standard error of the mean
from scipy import mean
from scipy.stats import sem


Y_LABEL = "Slowdown factor"
X_LABEL = "Browser"


import matplotlib as mpl

import matplotlib.pyplot as plt



fig = plt.figure()
ax = fig.add_subplot(111)


sampledata={}
for browser in ('firefox',
    'chrome',
    'internet-explorer'
    ):
    sampledata[browser] = {}
    for benchmark in  ('data1', 'data2', 'data3'):
        sampledata[browser][benchmark] = {}

sampledata['firefox']['data1'] = [10,5,20,10,15]
sampledata['chrome']['data1'] = [5,7,9,10,11]
sampledata['internet-explorer']['data1'] = [20,30,40,20,30]


sampledata['firefox']['data2'] = [10,50,20,10,14]
sampledata['chrome']['data2'] = [50,70,90,100,80]
sampledata['internet-explorer']['data2'] = [200,300,400,300,300]


sampledata['firefox']['data3'] = [90,50,100,100,140]
sampledata['chrome']['data3'] = [50,170,90,100,80]
sampledata['internet-explorer']['data3'] = [200,200,100,100,300]


data = {}
for browser in ('firefox',
    'internet-explorer'
    ):
    data[browser] = {}
    for benchmark in  ('data1', 'data2', 'data3',):
        data[browser][benchmark] = sampledata[browser][benchmark]

baselinedata = sampledata['chrome']

## the data
chrome_vanillas = [results_for_benchmark
             for results_for_benchmark in baselinedata.itervalues()]
chrome_vanilla_means = [mean(v) for v in chrome_vanillas]
chrome_vanilla_errors = [sem(v) for v in chrome_vanillas]

baseline_values = chrome_vanillas
baseline_means = chrome_vanilla_means

firefoxes = [results_for_benchmark
             for results_for_benchmark in data['firefox'].itervalues()]
firefoxes = [[float(v)/bl 
            for (v, bl) in zip(v_l, bl_l)]
            for (v_l, bl_l) in zip(firefoxes, baseline_values)]
firefox_means = [mean(v) for v in firefoxes]
firefox_errors = [sem(v) for v in firefoxes]



internet_explorers = [results_for_benchmark
             for results_for_benchmark in data['internet-explorer'].itervalues()]
internet_explorers = [[float(v)/bl
            for (v, bl) in zip(v_l, bl_l)]
            for (v_l, bl_l) in zip(internet_explorers, baseline_values)]
internet_explorer_means = [mean(v) for v in internet_explorers]
internet_explorer_errors = [sem(v) for v in internet_explorers]


N = min(len(browser) for browser in data.itervalues())
ind = np.arange(N)                # the x locations for the groups
width = 0.25                      # the width of the bars



# axes and labels
#ax.set_xlim(-width,len(ind)+width)
#ax.set_ylim(-45,45)
ax.set_ylabel(Y_LABEL)
ax.set_title(X_LABEL)
## the bars
firefox_rects = ax.bar(ind, firefox_means, width,
                color='green',
                yerr=firefox_errors,
                error_kw=dict(elinewidth=2,ecolor='black'))

internet_explorer_rects = ax.bar(ind+width, internet_explorer_means, width,
                    color='blue',
                    yerr=internet_explorer_errors,
                    error_kw=dict(elinewidth=2,ecolor='black'))

xTickMarks = [key
              for key in data.itervalues().next().keys()]
ax.set_xticks(ind+width)
xtickNames = ax.set_xticklabels(xTickMarks)
plt.setp(xtickNames, rotation=45, fontsize=10)

## add a legend
ax.legend( (firefox_rects[0], internet_explorer_rects[0]),
           ('Firefox', 'Internet Explorer') )

plt.savefig('figure.png')

plt.show()

现在,我希望将基线设置为1.0,并在值小于1时让条形条向下增长。我已经看到了参数bar函数,但它似乎只是将1添加到我所拥有的每一个值中,而不是将1作为绘制条形图的基础。

Matlab似乎能够很容易地做到这一点。,使用类似于set(hBars(1),'BaseValue',2);的东西:

因此,最终的问题是:如何创建一个以1.0为基线并让条形图向下生长的地块?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-20 17:11:39

您可以使用格式化程序的组合(用于刻度),并将1减去数据。

示例:

代码语言:javascript
复制
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

baseline = 1
data = [1.1,2.0,1.4,0.9,1.6,0.7,0.1]
plt.bar(range(len(data)),[x-baseline for x in data])
plt.gca().yaxis.set_major_formatter(mtick.FuncFormatter(lambda x,_: x+baseline))

plt.show()
票数 5
EN

Stack Overflow用户

发布于 2016-03-18 08:25:48

实际上,如果从bottom参数中减去基线,那么bar函数的height参数就可以做您想做的事情(由于某种原因,它不称为y:)

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt

baseline = 1
data = np.r_[1.1, 2.0, 1.4, 0.9, 1.6, 0.7, 0.1]
plt.bar(range(len(data)), data-baseline, bottom=baseline)

与@xndrme相比,这可能是一种更好的方法,因为:

  1. Y轴与原始数据(而不是差分数据)具有相同(且正确)的尺度,当您试图设置ylim或叠加另一个地块时,其好处将变得明显。
  2. 不需要额外的进口。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21914431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档