水平条形图中的Pyplot问题

0 投票
1 回答
530 浏览
提问于 2025-04-17 23:22

我正在绘制以下数据(存储在 C:\Plot 的 'sample_bar_plot.csv' 文件中):

    X           Y
A   12.60862266 13.88257739
B   18.69422707 20.66625712
C   13.54164413 18.49381352
D   11.35545631 13.12407667
E   9.979860808 11.33701054
F   8.496320019 8.838461563
G   11.94646631 16.28188825

绘制水平输出的 Python 代码如下:

import numpy as np
import matplotlib.pyplot as plt
import math, pdb, csv
import pylab, operator
from matplotlib import rcParams

base_dir  = 'C:\\Plot\\'
file_name = 'sample_bar_plot.csv'
header    = True
csv_data  = {}

with open(base_dir+file_name, mode='r') as infile:
    reader   = csv.reader(infile)
    for rows in reader:
        if header == True:
            header = False
            continue
        else:
            csv_data[rows[0]]=rows[1:3]

print csv_data

num_keys = len(csv_data.keys())
num_vals = len(csv_data.values()[0])

fig = plt.figure(figsize=(8,6))
ax = fig.add_axes([0.15, 0.15, 0.65, 0.7])
# remove top and right spines and turn ticks off if no spine
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.yaxis.set_tick_params(size=0)
ax.xaxis.set_ticks_position('bottom')
# postition of tick out
ax.tick_params(axis='bottom', direction='in', width=2, length=6,
                   labelsize=24, pad=8)

ax.spines['left'].set_linewidth(2)
ax.spines['bottom'].set_linewidth(2)
ax.set_yticklabels(['']+csv_data.keys())   
rcParams['ytick.direction'] = 'out'

# Find maximum value in dictionary
max_val = 0.0
for i,key in enumerate(csv_data.keys()):
    if(float(csv_data.values()[i][0]) > max_val):
        max_val = float(csv_data.values()[i][0])
    if(float(csv_data.values()[i][1]) > max_val):
        max_val = float(csv_data.values()[i][1])

plt.ylim((0,num_keys+1))
plt.xlim((0,int(max_val+5)))

idx = 1
for i,key in enumerate(csv_data.keys()):
    ax.barh([idx],float(csv_data.values()[idx-1][1]), height=0.1, facecolor='0.75',edgecolor='k', linewidth=0,align='center')
    cir = pylab.Circle((float(csv_data.values()[idx-1][1]),idx), radius=0.2,  fc='0.75',linewidth=0)
    pylab.gca().add_patch(cir)

    ax.barh([idx],float(csv_data.values()[idx-1][0]), height=0.1, facecolor='k',edgecolor='k', linewidth=0,align='center')
    cir = pylab.Circle((float(csv_data.values()[idx-1][0]),idx), radius=0.2,  fc='k',linewidth=0)
    pylab.gca().add_patch(cir)

    idx += 1   

plt.savefig(base_dir+'out.png')
plt.show()

不过,这个图表有几个问题:
1. 圆圈看起来更像椭圆。怎么才能修正这个?
2. x 轴的刻度应该向外延伸,而不是向内,但代码的表现正好相反。
3. 有几条线比其他的粗(比如 'A'、'B' 和 'F')。

有没有人能建议一下怎么解决这些问题?

谢谢!

在这里输入图片描述

1 个回答

1

把你最开始的几行代码改成下面这样,你就可以正常使用了。

我无法重现你提到的第三个问题。

你提到的第一个问题是和比例有关的。

对于第二个问题,你需要修改一下 rcParams

num_keys = len(csv_data.keys())
num_vals = len(csv_data.values()[0])
rcParams['xtick.direction'] = 'out'
fig = plt.figure(figsize=(8,6))
ax = fig.add_axes([0.15, 0.15, 0.65, 0.7], aspect='equal')

你已经定义了图形的大小。所以如果我们把比例设置为 equal,就会出现很大一片空白区域,看看附上的图。

在这里输入图片描述

撰写回答