自定义多彩水平条形图matplotlib

3
我想创建一个水平条形图,每个条形都有自定义的条纹颜色方案(类似于下面的图)。我熟悉创建普通的barhplot,但我不知道如何使用双色方案。

enter image description here

尝试过的代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.DataFrame({"P1_P2": [0.20],
                   "P1_P3": [0.16],
                   "P2_P5": [0.12],
                   "P3_P5": [0.06],
                   "P3_P6": [0.06],
                   "P5_P6": [0.06]})
df=df.T

fig, ax = plt.subplots(dpi=600, figsize=(4, 4), nrows=1, ncols=1, facecolor=None, edgecolor='black')

df.plot.barh(ax=ax, position=0.50, width=0.3, color=(245/255, 153/255, 145/255, 1.0))
ax.get_legend().remove()

plt.show()
2个回答

3
你可以使用不同的颜色来填充每个条形图。线条的宽度需要根据特定的绘图进行调整。
由于填充和轮廓使用相同的颜色,因此可以创建一个仅显示轮廓的条形图副本。
import matplotlib.pyplot as plt
from matplotlib import rcParams
import pandas as pd
from copy import copy

df = pd.DataFrame([0.2 , 0.16, 0.12, 0.06, 0.06, 0.06], index=['P1_P2', 'P1_P3', 'P2_P5', 'P3_P5', 'P3_P6', 'P5_P6'])
first_colors = ['dodgerblue', 'orange', 'green','silver', 'silver', 'dodgerblue']
second_colors = ['crimson', 'crimson', 'dodgerblue', 'dodgerblue', 'green', 'gold']

fig, ax = plt.subplots(dpi=600, figsize=(4, 4), nrows=1, ncols=1, facecolor=None, edgecolor='black')

df.plot.barh(ax=ax, position=0.50, width=0.3, legend=False, linewidth=0)

rcParams['hatch.linewidth'] = 4
for bar, main_color, hatch_color in zip(ax.containers[0], first_colors, second_colors):
    rect = copy(bar)
    rect.set_facecolor('none')
    rect.set_edgecolor('black')
    rect.set_linewidth(2)
    ax.add_patch(rect)
    bar.set_facecolor(main_color)
    bar.set_edgecolor(hatch_color)
    bar.set_hatch('//')
ax.invert_yaxis()
plt.tight_layout()
plt.show()

多色斜线条形图

提示:更简单的方法是先绘制两次条形图的轮廓,然后更新首先绘制的条形图的颜色和斜线填充(第一组条形图存储在ax.containers[0]中)。

for _ in range(2):
    df.plot.barh(ax=ax, position=0.50, width=0.3, legend=False, fc='none', ec='black', lw=2)
rcParams['hatch.linewidth'] = 4
for bar, main_color, hatch_color in zip(ax.containers[0], first_colors, second_colors):
    bar.set_linewidth(0)
    bar.set_facecolor(main_color)
    bar.set_edgecolor(hatch_color)
    bar.set_hatch('//')

正是我想要的!我在各个地方都在寻找这个。改变线条粗细的技巧解决了问题。 - Matthi9000

2

可以通过在barh中使用facecoloredgecolor参数来实现。我看到您已经在subplots中使用了以下参数。下面的解决方案重新创建并生成了图表:

%matplotlib

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

df = pd.DataFrame({"P1_P2": [0.20],
                   "P1_P3": [0.16],
                   "P2_P5": [0.12],
                   "P3_P5": [0.06],
                   "P3_P6": [0.06],
                   "P5_P6": [0.06]})
df=df.T

fig, ax = plt.subplots(dpi=600, figsize=(4, 4), nrows=1, ncols=1)

df.plot.barh(ax=ax, position=0.50, width=0.3, facecolor="red", 
                     edgecolor="blue")
ax.get_legend().remove()

plt.show()

为了在颜色之间添加条纹,可以使用以下代码中提到的参数hatch
%matplotlib

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

df = pd.DataFrame({"P1_P2": [0.20],
                   "P1_P3": [0.16],
                   "P2_P5": [0.12],
                   "P3_P5": [0.06],
                   "P3_P6": [0.06],
                   "P5_P6": [0.06]})
df=df.T

fig, ax = plt.subplots(dpi=600, figsize=(4, 4), nrows=1, ncols=1)

df.plot.barh(ax=ax, position=0.50, width=0.3, facecolor="red", 
                     edgecolor="blue", hatch=r'//')
ax.get_legend().remove()

plt.show()

图表将如下所示:

striped picture

如果您想增加或减少线条宽度,可以使用plt.rcParams["hatch.linewidth"]进行更改。

plt.rcParams["hatch.linewidth"]= 4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接