如何在 python 中的垂直条形图下方制作水平颜色轨道
How to make a horizontal color track underneath a vertical bar plot in python
我正在尝试绘制如下所示的条形图:vertical stacked barplot with a horizontal bar underneath
我使用以下代码在 python 中制作了实际的垂直条形图:
fig, ax = plt.subplots(figsize=[15, 5])
width = 0.75
ax.bar(labels, my_order["relapse"], width, label=SAMPLE[0], color = "r")
ax.bar(labels, my_order['remission'], width, bottom=my_order['relapse'], label=SAMPLE[1], color = "orange")
ax.set_title('Ratio of cells by patient in each cluster')
ax.legend(bbox_to_anchor=(1.01,0.5), loc='center left')
my_order
是一个数据框,其中包含一列复发数字和一列缓解数字。我无法创建的部分是下方的单杠。这将根据不同条形图的其他属性进行着色(每个条形图代表一个集群,在这种情况下,如果集群有一个 属性,我想将水平图着色为蓝色,如果有另一个,则为黄色)。有谁知道在 python 中是否可以这样做?或者如果我必须手动执行此操作?在完整的数据集中,整个图中有大约 50 个条形图,因此找到一种不手动执行此操作的方法会很棒。
您可以遍历每个条形位置,并创建一个与条形宽度相同但略低于绘图的彩色矩形。
rectangle 有以下参数:
(x, y), width, height
transform=ax.get_xaxis_transform()
:在 x 方向上,值在 "data coordinates" 中测量,这里是 0, 1, 2, ...
用于柱位置;在 y 方向上使用“轴坐标”,从绘图区域顶部的 1 到底部的 0,下面的位置使用负值
clip_on=False
:正常情况下,当某些东西放在绘图区域之外时,它会被剪掉; clip_on=False
覆盖该行为
facecolor=...
:内饰颜色
edgecolor='black'
: 黑边
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
labels = [*'abcdefghijklmnopqrst']
my_order = pd.DataFrame({'relapse': np.random.randint(11, 51, 20),
'remission': np.random.randint(11, 51, 20),
'cluster': np.random.randint(1, 3, 20)})
fig, ax = plt.subplots(figsize=[15, 5])
width = 0.75
ax.bar(labels, my_order['relapse'], width, label='SAMPLE[0]', color='crimson')
ax.bar(labels, my_order['remission'], width, bottom=my_order['relapse'], label='SAMPLE[1]', color='orange')
ax.set_title('Ratio of cells by patient in each cluster')
legend1 = ax.legend(title='Samples', bbox_to_anchor=(1.01, 0.5), loc='center left')
ax.margins(x=0.01)
color_for_cluster = {1: 'skyblue', 2: 'yellow'}
for i, cluster in enumerate(my_order['cluster']):
ax.add_patch(plt.Rectangle((i - width / 2, -0.1), width, 0.02,
facecolor=color_for_cluster[cluster], edgecolor='black',
transform=ax.get_xaxis_transform(), clip_on=False))
handles = [plt.Rectangle((0, 0), 0, 0, facecolor=color_for_cluster[cluster], edgecolor='black', label=cluster)
for cluster in color_for_cluster]
legend2 = ax.legend(handles=handles, title='Clusters', bbox_to_anchor=(1.01, -0.01), loc='lower left')
ax.add_artist(legend1) # add the legend again, because the second call to ax.legend removes the first legend
fig.tight_layout()
plt.show()
您也可以使用 plt.Rectangle((i - 1/2, -0.1), 1, 0.02, ...)
让矩形占据整个宽度。
我正在尝试绘制如下所示的条形图:vertical stacked barplot with a horizontal bar underneath
我使用以下代码在 python 中制作了实际的垂直条形图:
fig, ax = plt.subplots(figsize=[15, 5])
width = 0.75
ax.bar(labels, my_order["relapse"], width, label=SAMPLE[0], color = "r")
ax.bar(labels, my_order['remission'], width, bottom=my_order['relapse'], label=SAMPLE[1], color = "orange")
ax.set_title('Ratio of cells by patient in each cluster')
ax.legend(bbox_to_anchor=(1.01,0.5), loc='center left')
my_order
是一个数据框,其中包含一列复发数字和一列缓解数字。我无法创建的部分是下方的单杠。这将根据不同条形图的其他属性进行着色(每个条形图代表一个集群,在这种情况下,如果集群有一个 属性,我想将水平图着色为蓝色,如果有另一个,则为黄色)。有谁知道在 python 中是否可以这样做?或者如果我必须手动执行此操作?在完整的数据集中,整个图中有大约 50 个条形图,因此找到一种不手动执行此操作的方法会很棒。
您可以遍历每个条形位置,并创建一个与条形宽度相同但略低于绘图的彩色矩形。
rectangle 有以下参数:
(x, y), width, height
transform=ax.get_xaxis_transform()
:在 x 方向上,值在 "data coordinates" 中测量,这里是0, 1, 2, ...
用于柱位置;在 y 方向上使用“轴坐标”,从绘图区域顶部的 1 到底部的 0,下面的位置使用负值clip_on=False
:正常情况下,当某些东西放在绘图区域之外时,它会被剪掉;clip_on=False
覆盖该行为facecolor=...
:内饰颜色edgecolor='black'
: 黑边
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
labels = [*'abcdefghijklmnopqrst']
my_order = pd.DataFrame({'relapse': np.random.randint(11, 51, 20),
'remission': np.random.randint(11, 51, 20),
'cluster': np.random.randint(1, 3, 20)})
fig, ax = plt.subplots(figsize=[15, 5])
width = 0.75
ax.bar(labels, my_order['relapse'], width, label='SAMPLE[0]', color='crimson')
ax.bar(labels, my_order['remission'], width, bottom=my_order['relapse'], label='SAMPLE[1]', color='orange')
ax.set_title('Ratio of cells by patient in each cluster')
legend1 = ax.legend(title='Samples', bbox_to_anchor=(1.01, 0.5), loc='center left')
ax.margins(x=0.01)
color_for_cluster = {1: 'skyblue', 2: 'yellow'}
for i, cluster in enumerate(my_order['cluster']):
ax.add_patch(plt.Rectangle((i - width / 2, -0.1), width, 0.02,
facecolor=color_for_cluster[cluster], edgecolor='black',
transform=ax.get_xaxis_transform(), clip_on=False))
handles = [plt.Rectangle((0, 0), 0, 0, facecolor=color_for_cluster[cluster], edgecolor='black', label=cluster)
for cluster in color_for_cluster]
legend2 = ax.legend(handles=handles, title='Clusters', bbox_to_anchor=(1.01, -0.01), loc='lower left')
ax.add_artist(legend1) # add the legend again, because the second call to ax.legend removes the first legend
fig.tight_layout()
plt.show()
您也可以使用 plt.Rectangle((i - 1/2, -0.1), 1, 0.02, ...)
让矩形占据整个宽度。