为什么条形图中只使用了一个影线?

Why is only one hatch used in the bar graph?

我使用 pandas 生成了以下条形图。我的问题是所有的条都有相同的图案。我尝试了很多方法,但无法解决这个问题。

此外,图例中只显示了一个条目(对于最后一个子图)。

使用的数据是

密码是:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
class ScalarFormatterForceFormat(ScalarFormatter):
    def _set_format(self):  # Override function that finds format to use.
        self.format = "%1.1f"  # Give format here
patterns = [ "\" , "/" , "-","+" ,"x", "|", '.',  "O" ]
yfmt = ScalarFormatterForceFormat()
yfmt.set_powerlimits((0, 0))

bar_gap=0.005
bar_width=0.01

bar_pos = [0 for i in range(5)]
bar_pos[0]=bar_gap
for i in range(1,5):
    bar_pos[i]=bar_pos[i-1]+bar_gap+bar_width
colors = ['tab:blue', 'tab:green', 'tab:orange', 'tab:red','tab:olive']
patterns = [ "\" , "/" , "+" , "-", ".", "*","x", "o", "O" ]

# file_locn = ''r'C:\Users\girum\Desktop\Throughput.csv'''
file_locn = ''r'my_file.csv'''
df = pd.read_csv(file_locn,index_col='Set')
df=df.T
fig, axes = plt.subplots(1,3,figsize=(8,5))#,sharey=True)
for i in range(3):
    axes[i].yaxis.set_major_formatter(yfmt)
df.Type_A.plot(ax=axes[0],kind='bar',color=colors)
df.Type_B.plot(ax=axes[1],kind='bar',color=colors)
df.Type_C.plot(ax=axes[2],kind='bar',color=colors)

handles, labels = axes[0].get_legend_handles_labels()
for ax in fig.axes:
    bars = ax.patches
    hatches = ''.join(h*len(df) for h in patterns)

    for bar, hatch in zip(bars, hatches):
        bar.set_hatch(2*hatch)

plt.xticks(rotation=360)
axes[0].set_ylabel('Speed')
for i in range(len(df)):
    axes[i].set_xlabel('')#Why is this line not working
    axes[i].tick_params(axis='x', rotation=360)

plt.legend(loc='center right', bbox_to_anchor=(.2,1.08), ncol=1)

plt.show()

您加入 patterns 的行生成了您不想要的结果。

patterns = [ "\" , "/" , "+" , "-", ".", "*","x", "o", "O" ]
hatches = ''.join(h*3 for h in patterns)
>>> '\\\///+++---...***xxxoooOOO'

# if you have the bars, this is the output
for bar, hatch in zip([0,1,3], hatches):
    print(2*hatch)
>>>
\
\
\

尝试直接在循环中使用模式来简化此部分:

for bar, hatch in zip([0,1,3], patterns):
    print(2*hatch)`
>>>
\
//
++

输出

我使用您提供的代码和数据创建了这个输出。

下面的代码有以下变化:

  • 添加了一些虚拟测试数据以启用stand-alone测试代码
  • 删除了一些未使用的变量
  • 使用未更改的 ScalarFormatter
  • 只有一个循环通过 axes 并避开 plt 接口
  • 使用ax.containers[0]捕捉条形容器(ax.patches是矩形列表,没有周围的容器)
  • 将条形容器的标签更改为_no_legend,因此它不会出现在图例中
  • 直接使用模式而不是连接它们
  • 已删除 h*len(df);请注意,将 '/' 等字符串乘以例如4、重复字符串(到'////');在 matplotlib 中使用重复模式使基本模式更密集
  • 使用 tick_params(axis='x', labelbottom=False, length=0) 删除刻度标签
  • 为各个条形图添加了标签,以便它们出现在图例中
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter

yfmt = ScalarFormatter()
yfmt.set_powerlimits((-9, 9))

colors = ['tab:blue', 'tab:green', 'tab:orange', 'tab:red', 'tab:olive']
patterns = ["\", "/", "+", "-", ".", "*", "x", "o", "O"]

df = pd.DataFrame(np.random.randint(100000, 500000, (3, 3)),
                  columns=['A', 'B', 'C'],
                  index=['Type_A', 'Type_B', 'Type_C'])
df = df.T
fig, axes = plt.subplots(1, 3, figsize=(8, 5))
df.Type_A.plot(ax=axes[0], kind='bar', color=colors)
df.Type_B.plot(ax=axes[1], kind='bar', color=colors)
df.Type_C.plot(ax=axes[2], kind='bar', color=colors)

for ax in axes:
    bars = ax.containers[0]
    bars.set_label('_no_legend')
    hatches = [h * 2 for h in patterns]
    for bar, hatch, label in zip(bars, hatches, df.index):
        bar.set_hatch(2 * hatch)
        bar.set_label(label)
    ax.yaxis.set_major_formatter(yfmt)
    ax.tick_params(axis='x', labelbottom=False, length=0)

axes[0].set_ylabel('Speed')

axes[2].legend(loc='lower right', bbox_to_anchor=(1, 1.01), ncol=3)
plt.tight_layout()
plt.show()