由于可读性原因,我试图在直方图中注释海洋中的堆叠直方图,并为直方图中的每个段带有色调。我已经连接了下面的示例数据以及目前正在做的事情:
示例数据: https://easyupload.io/as5uxs < /a>
当前代码以组织和显示图:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# create the dataframe - from sample data file
data = {'brand': ['Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'BMW', 'BMW', 'BMW', 'BMW', 'BMW', 'GM', 'GM', 'GM', 'GM', 'GM', 'GM', 'Toyota', 'Toyota'],
'Model': ['A3', 'A3', 'A3', 'A5', 'A5', 'RS5', 'RS5', 'RS5', 'RS5', 'M3', 'M3', 'M3', 'X1', 'X1', 'Chevy', 'Chevy', 'Chevy', 'Chevy', 'Caddy', 'Caddy', 'Camry', 'Corolla']}
data = pd.DataFrame(data)
# make the column categorical, using the order of the 'value_counts'
data['brand'] = pd.Categorical(data['brand'], data['brand'].value_counts(sort=True).index)
# We want to sort the hue value (model) alphabetically
hue_order = data['Model'].unique()
hue_order.sort()
f, ax = plt.subplots(figsize=(10, 6))
sns.histplot(data, x="brand", hue="Model", multiple="stack", edgecolor=".3", linewidth=.5, hue_order=hue_order, ax=ax)
这将生成一个带有有序传奇和有序条的好图。但是,当我尝试使用多种方法注释时,我似乎无法使它起作用。我所追求的是具有色调的注释,然后是酒吧的高度(使用该制造商的车辆数量)。因此,例如,对于第一个栏,我希望它在第一个灰色阴影单元格中显示RS5X 4,以演示RS5型号的4辆车,依此类推,依此类推,依此类推。
我已经尝试了很多方法,并且正在努力使它起作用。我已经尝试使用过:
for i, rect in enumerate(ax.patches):
# Find where everything is located
height = rect.get_height()
width = rect.get_width()
x = rect.get_x()
y = rect.get_y()
# The height of the bar is the count value and can used as the label
label_text = f'{height:.0f}'
label_x = x + width / 2
label_y = y + height / 2
# don't include label if it's equivalently 0
if height > 0.001:
ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=8)
当前结果
I am trying to annotate a stacked histogram in Seaborn with the hue for each segment in the histogram for readability reasons. I've attached sample data below and what I'm currently doing:
Sample data: https://easyupload.io/as5uxs
Current code to organize and display the plot:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# create the dataframe - from sample data file
data = {'brand': ['Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'Audi', 'BMW', 'BMW', 'BMW', 'BMW', 'BMW', 'GM', 'GM', 'GM', 'GM', 'GM', 'GM', 'Toyota', 'Toyota'],
'Model': ['A3', 'A3', 'A3', 'A5', 'A5', 'RS5', 'RS5', 'RS5', 'RS5', 'M3', 'M3', 'M3', 'X1', 'X1', 'Chevy', 'Chevy', 'Chevy', 'Chevy', 'Caddy', 'Caddy', 'Camry', 'Corolla']}
data = pd.DataFrame(data)
# make the column categorical, using the order of the 'value_counts'
data['brand'] = pd.Categorical(data['brand'], data['brand'].value_counts(sort=True).index)
# We want to sort the hue value (model) alphabetically
hue_order = data['Model'].unique()
hue_order.sort()
f, ax = plt.subplots(figsize=(10, 6))
sns.histplot(data, x="brand", hue="Model", multiple="stack", edgecolor=".3", linewidth=.5, hue_order=hue_order, ax=ax)
This generates a nice plot with an ordered legend and ordered bars. However when I try annotate using a number of methods, I can't seem to get it to work. What I am after is the annotation to have the hue, and then the height of the bar (the number of vehicles with that manufacturer). So for example, for the first bar, I would want it to display RS5x 4 in the first grey shaded cell to demonstrate 4 vehicles of RS5 model, and so on for each segment of the stacked histogram.
I've tried a lot of methods and am struggling to get this to work. I've tried using:
for i, rect in enumerate(ax.patches):
# Find where everything is located
height = rect.get_height()
width = rect.get_width()
x = rect.get_x()
y = rect.get_y()
# The height of the bar is the count value and can used as the label
label_text = f'{height:.0f}'
label_x = x + width / 2
label_y = y + height / 2
# don't include label if it's equivalently 0
if height > 0.001:
ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=8)
Current Result

But this only displays the height of the bar, which is great, but I am not sure how to get the correct hue text to display along with that height.
发布评论
评论(1)
pd.crosstab
,它将用'brand'
作为索引,'Model'作为列,计数将是值。
'a3'
,然后'a5'
等。。
代码>)。有9个
barcontiners
,与每一列相对应。枚举(ax.Patches)
,因为有36个补丁。python 3.10
,PANDAS 1.4.2
,matplotlib 3.5.1
设置和重塑
图
pd.crosstab
, which will create a wide dataframe with'brand'
as the index,'Model'
as the columns, and the counts will be the values.'A3'
is plotted, then'A5'
, etc.enumerate(ax.containers)
, and then usei
to indexcol
(e.g.col[i]
). There are 9BarContiners
, which correspond to each column.enumerate(ax.patches)
, because there are 36 patches..bar_label
for annotationspython 3.10
,pandas 1.4.2
,matplotlib 3.5.1
Setup and Reshape
Plot and Annotate