如何将xaxis值转换为matplotlib条形图的图例

2024-09-28 13:21:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为来自系列的数据创建条形图。但是,名称(x轴值)非常长。如果将它们旋转90度,则无法读取整个名称并获得图形的良好图像。45度也好不到哪里去。我正在寻找一种方法,用数字1-15标记x轴,然后用图例列出每个数字对应的名称

这是我到目前为止完成的函数,包括从更大的数据帧创建系列

def graph_average_expressions(TAD_matches, CAGE): 
"""graphs the top 15 expression levels of each lncRNA"""

for i, row in TAD_matches.iterrows():
    mask = (
        CAGE['short_description'].isin(row['peak_ID'])
    )#finds expression level for peaks in an lncRNA
    average = CAGE[mask].iloc[:,8:].mean(axis=0).astype('float32').sort_values().tail(n=15)
    #made a new df of the top 15 highest expression levels for all averaged groups 
    #a group is peaks belong to the same lncRNA
    cell_type = list(average.index)
    expression = list(average.values)
    average_df = pd.DataFrame(
        list(zip(cell_type, expression)), 
        columns=['cell_type','expression']
    )
    colors = sns.color_palette(
        'husl', 
        n_colors=len(cell_type)
    )
    p = sns.barplot(
        x=average_df.index, 
        y='expression', 
        data=average_df, 
        palette=colors
    )
    cmap = dict(zip(average_df.cell_type, colors))
    patches = [Patch(color=v, label=k) for k, v in cmap.items()]
    plt.legend(
        handles=patches, 
        bbox_to_anchor=(1.04, 0.5), 
        loc='center left', 
        borderaxespad=0
    )
    plt.title('expression_levels_of_lncRNA_' + row['lncRNA_name'])
    plt.xlabel('cell_type')
    plt.ylabel('expression')
    plt.show()

下面是我正在绘制的数据示例

CD14_monocytes_treated_with_Group_A_streptococci_donor2.CNhs13532         1.583428
Neutrophils_donor3.CNhs11905                                              1.832527
CD14_monocytes_treated_with_Trehalose_dimycolate_TDM_donor2.CNhs13483     1.858384
CD14_monocytes_treated_with_Candida_donor1.CNhs13473                      1.873013
CD14_Monocytes_donor2.CNhs11954                                           2.041607
CD14_monocytes_treated_with_Candida_donor2.CNhs13488                      2.112112
CD14_Monocytes_donor3.CNhs11997                                           2.195365
CD14_monocytes_treated_with_Group_A_streptococci_donor1.CNhs13469         2.974203
Eosinophils_donor3.CNhs12549                                              3.566822
CD14_monocytes_treated_with_lipopolysaccharide_donor1.CNhs13470           3.685389
CD14_monocytes_treated_with_Salmonella_donor1.CNhs13471                   4.409062
CD14_monocytes_treated_with_Candida_donor3.CNhs13494                      5.546789
CD14_monocytes_-_treated_with_Group_A_streptococci_donor3.CNhs13492       5.673991
Neutrophils_donor1.CNhs10862                                              8.352045
Neutrophils_donor2.CNhs11959                                             11.595509

使用上面的新代码,这是我得到的图形,但没有图例或标题。 This is my graph


Tags: dffortypewithcellpltaverageexpression
2条回答

设置数据帧

  1. 验证要绘制的数据帧的索引已重置,因此它是从0开始的整数,并将该索引用作x轴
  2. 在y轴上绘制值

备选方案1A:Seaborn hue

  • 最简单的方法可能是使用seaborn.barplot并将hue参数与'names'一起使用
  • Seaborn: Choosing color palettes
    • 此绘图正在使用husl
    • 有关husl调色板的其他选项,请访问^{}
  • 对于此选项,条形图不会居中,因为它们是根据色调级别的数量放置的,在这种情况下有15个级别
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# plt styling parameters
plt.style.use('seaborn')
plt.rcParams['figure.figsize'] = (16.0, 10.0)
plt.rcParams["patch.force_edgecolor"] = True

# create a color palette the length of the dataframe
colors = sns.color_palette('husl', n_colors=len(df))

# plot
p = sns.barplot(x=df.index, y='values', data=df, hue='names')

# place the legend to the right of the plot
plt.legend(bbox_to_anchor=(1.04, 0.5), loc='center left', borderaxespad=0)

enter image description here

备选方案1B:Seaborn palette

  • 使用palette参数而不是hue,将条直接放置在刻度上
  • 此选项需要“手动”将'names'与颜色关联并创建图例。
    • ^{}使用Patch创建图例中的每个项目。(例如,与颜色和名称关联的矩形)
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.patches import Patch

# create a color palette the length of the dataframe
colors = sns.color_palette('husl', n_colors=len(df))

# plot
p = sns.barplot(x=df.index, y='values', data=df, palette=colors)

# create color map with colors and df.names
cmap = dict(zip(df.names, colors))

# create the rectangles for the legend
patches = [Patch(color=v, label=k) for k, v in cmap.items()]

# add the legend
plt.legend(handles=patches, bbox_to_anchor=(1.04, 0.5), loc='center left', borderaxespad=0)

enter image description here

备选案文2:^{}

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.patches import Patch

# plt styling parameters
plt.style.use('seaborn')
plt.rcParams['figure.figsize'] = (16.0, 10.0)
plt.rcParams["patch.force_edgecolor"] = True

# chose a color map with enough colors for the number of bars
colors = [plt.cm.tab20c(np.arange(len(df)))]

# plot the dataframe
df.plot.bar(color=colors)

# create color map with colors and df.names
cmap = dict(zip(df.names, colors[0]))

# create the rectangles for the legend
patches = [Patch(color=v, label=k) for k, v in cmap.items()]

# add the legend
plt.legend(handles=patches, bbox_to_anchor=(1.04, 0.5), loc='center left', borderaxespad=0)

enter image description here

可复制数据帧

data = {'names': ['CD14_monocytes_treated_with_Group_A_streptococci_donor2.CNhs13532', 'Neutrophils_donor3.CNhs11905', 'CD14_monocytes_treated_with_Trehalose_dimycolate_TDM_donor2.CNhs13483', 'CD14_monocytes_treated_with_Candida_donor1.CNhs13473', 'CD14_Monocytes_donor2.CNhs11954', 'CD14_monocytes_treated_with_Candida_donor2.CNhs13488', 'CD14_Monocytes_donor3.CNhs11997', 'CD14_monocytes_treated_with_Group_A_streptococci_donor1.CNhs13469', 'Eosinophils_donor3.CNhs12549', 'CD14_monocytes_treated_with_lipopolysaccharide_donor1.CNhs13470', 'CD14_monocytes_treated_with_Salmonella_donor1.CNhs13471', 'CD14_monocytes_treated_with_Candida_donor3.CNhs13494', 'CD14_monocytes_-_treated_with_Group_A_streptococci_donor3.CNhs13492', 'Neutrophils_donor1.CNhs10862', 'Neutrophils_donor2.CNhs11959'],
        'values': [1.583428, 1.832527, 1.858384, 1.873013, 2.041607, 2.1121112, 2.195365, 2.974203, 3.566822, 3.685389, 4.409062, 5.546789, 5.673991, 8.352045, 11.595509]}

df = pd.DataFrame(data)

有点不同的路线。制作一个字符串x值映射到名称,并将其添加到图形中

制作了我自己的数据框以供说明

from matplotlib import pyplot as plt
import pandas as pd
import string,random
df = pd.DataFrame({'name':[''.join(random.sample(string.ascii_letters,15))
                           for _ in range(10)],
                   'data':[random.randint(1,20) for _ in range(10)]})

制作情节

fig,ax = plt.subplots()
ax.bar(df.index,df.data)

制作图例

x_legend = '\n'.join(f'{n} - {name}' for n,name in zip(df.index,df['name']))

添加图例作为文本艺术家,并调整绘图以适应它

t = ax.text(.7,.2,x_legend,transform=ax.figure.transFigure)
fig.subplots_adjust(right=.65)

plt.show()
plt.close()

enter image description here


通过获取并使用文本艺术家的大小和人物的大小,可以使其动态

# using imports and DataFrame from above
fig,ax = plt.subplots()
r = fig.canvas.get_renderer()

ax.bar(df.index,df.data)
x_legend = '\n'.join(f'{n} - {name}' for n,name in zip(df.index,df['name']))
t = ax.text(0,.1,x_legend,transform=ax.figure.transFigure)

# find the width of the Text and place it on the right side of the Figure
twidth = t.get_window_extent(renderer=r).width
*_,fwidth,fheight = fig.bbox.extents
tx,ty = t.get_position()
tx =  .95 - (twidth/fwidth)
t.set_position((tx,ty))

# adjust the right edge of the plot/Axes
ax_right = tx - .05
fig.subplots_adjust(right=ax_right)

相关问题 更多 >

    热门问题