Python组合图在条形图上添加百分比但错误

标签 python pandas matplotlib visualization seaborn

我尝试在组合图、折线图和柱形图中的条形图上添加百分比。
然而,所有显示的值都是困惑的。

我在这里提供数据,这也是我的previous post答案由 Quang Hoang 提供。

Group   yq        Value1    Value2
G       2014Q1     0.07        1.1
G       2014Q2     0.06        1.09
G       2014Q3     0.09        1.11
G       2014Q4     0.04        1.13
I       2014Q1     0.10        1.2
I       2014Q2     0.13        1.25
I       2014Q3     0.15        1.23
I       2014Q4     0.18        1.4

我提供了我尝试过的代码:

fig, ax1 = plt.subplots(figsize=(7,5))
ax2=ax1.twinx()
sns.lineplot(x='yq',y='Value2', data=dataset, hue='Group', ax=ax1, legend = None)
ax1.set_xticklabels(ax1.get_xticks(), rotation=45)
ax1.set_ylabel("")
ax1.set_ylim((min(dataset['Value2']) - 0.05, max(dataset['Value2']) + 0.05))
sns.barplot(x='yq', y='Value1', data=dataset, hue='Group',ax=ax2)
ax2.set_yticklabels(['{:.1f}%'.format(a*100) for a in ax2.get_yticks()])
ax2.set_ylabel("")
for index, row in dataset.iterrows():
    ax2.text(row.name,row['Value1'], '{:.1f}%'.format(round(row['Value1'],2)), color='black')
plt.show()

绘图上显示的百分比很困惑,并且未正确放置在每个条形图和组上。
我搜索了herehere但我无法解决它。
有什么解决办法吗?

我提供我的结果:
enter image description here

我还提供了由 R 的包 ggplot2 创建的正确结果图像。
Python 中有两个与 ggplot2 类似的包:plotnine 和 ggplot。但是,我无法在 Python 中使用它。
enter image description here

如果有帮助的话,我提供我的 R 代码作为您的引用:

library(data.table)
library(ggplot2)
library(zoo)
dataset <- fread("Group   yq        Value1    Value2
G       2014/1/1     0.07        1.1
G       2014/4/1     0.06        1.09
G       2014/7/1     0.09        1.11
G       2014/10/1     0.04        1.13
I       2014/1/1     0.10        1.2
I       2014/4/1     0.13        1.25
I       2014/7/1     0.15        1.23
I       2014/10/1     0.18        1.4", header = T)
dataset$yq <- as.Date(dataset$yq)
dataset[, yq := as.yearqtr(dataset$yq, format = "%Y-%m-%d")]

ggplot(data = dataset, aes(x = yq, colour = Group, fill = Group,
                           label = scales::percent(Value1, accuracy = 0.1))) + 
  geom_col(aes(y = sec_axis_mult * Value1), position = position_dodge2(width = 0)) +
  geom_line(aes(y = Value2)) +
  scale_colour_manual(values = c("red", "darkblue"), labels = c("G", "I")) +
  scale_fill_manual(values = c("red", "darkblue"), labels = NULL, breaks = NULL) +
  scale_x_yearqtr(format = "%YQ%q", breaks = unique(dataset$yq)) +
  scale_y_continuous(name = "Value2",
                     sec.axis = sec_axis(~./sec_axis_mult, name = "Value1",
                                         labels = scales::percent)) +
  theme_bw() +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.title.y.right = element_blank(),
        axis.ticks.x=element_blank(),
        axis.ticks.y=element_blank(),
        axis.text.x=element_text(angle = 45, size = 12, vjust = 0.5, face = "bold"),
        axis.text.y=element_blank(),
        axis.line = element_line(colour = "white"),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        plot.background=element_blank(),
        legend.position="left",
        legend.title=element_blank(),
        legend.text = element_text(size = 16, face = "bold"),
        legend.key = element_blank(),
        legend.box.background =  element_blank()) +
  guides(colour = guide_legend(override.aes = list(shape = 15, size = 10))) +
  geom_text(data = dataset, aes(y = sec_axis_mult * Value1, colour = Group), 
            position = position_dodge(width = 0.25),
            vjust = -0.3, size = 4)

最佳答案

我正在做的是根据 bar 函数绘制的每个面片的坐标动态地标记条形图。

fig, ax1 = plt.subplots(figsize=(7,5))
ax2=ax1.twinx()
sns.lineplot(x='yq',y='Value2', data=dataset, hue='Group', ax=ax1, legend = None)
ax1.set_xticklabels(ax1.get_xticks(), rotation=45)
ax1.set_ylabel("")
ax1.set_ylim((min(dataset['Value2']) - 0.05, max(dataset['Value2']) + 0.05))
sns.barplot(x='yq', y='Value1', data=dataset, hue='Group',ax=ax2)
ax2.set_yticklabels(['{:.1f}%'.format(a*100) for a in ax2.get_yticks()])
ax2.set_ylabel("")
#iterate through each group of bars
for group in ax2.containers:
    for bar in group:
        #label the bar graphs based on the coordinates of the bar patches
        ax2.text(
            bar.get_xy()[0]+bar.get_width()/2,
            bar.get_height(), 
            '{:.1f}%'.format(round(100*bar.get_height(),2)), 
            color='black',
            horizontalalignment='center'
        )

输出: enter image description here

我调整了代码,以更紧密地匹配添加到原始问题中的所需输出。

fig, ax1 = plt.subplots(figsize=(7,5))
ax2=ax1.twiny().twinx()
sns.lineplot(x='yq',y='Value2', data=dataset, hue='Group', ax=ax1, legend = None)
ax1.set_xticklabels(dataset['yq'], rotation=45)
ax1.set_ylabel("")
ax1.set_ylim((0, max(dataset['Value2']) + 0.05))
ax2.set_ylim(0, max(dataset['Value2']) + 0.05)
sns.barplot(x='yq', y='Value1', data=dataset, hue='Group',ax=ax2)

#iterate through each group of bars
for group in ax2.containers:
    for bar in group:
        #label the bar graphs based on the coordinates of the bar patches
        ax2.text(
            bar.get_xy()[0]+bar.get_width()/2,
            bar.get_height(), 
            '{:.1f}%'.format(100*bar.get_height()), 
            color='black',
            horizontalalignment='center'
        )

ax1.yaxis.set_visible(False)
ax2.yaxis.set_visible(False)
ax2.xaxis.set_visible(False)

输出: enter image description here

关于Python组合图在条形图上添加百分比但错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56397222/

相关文章:

python - 如何在keras批量更新期间缩放梯度?

python - 如何在 Jenkins + Docker 中为 PostgreSQL 以外的数据库指定不同的名称

python-3.x - 我的条形图未显示所有数据值的条形图

python - 如何从 Python 中的所有行和列数组中找到单个最大值并显示其行和列索引

python-3.x - 如何从Python数组创建对象

python - 设置matplotlib表格的行边缘颜色

python - 训练集和测试集中不同数量的特征 - 随机森林 sklearn Python

Python - 正则表达式 - 特殊字符和 ñ

python - 使用 matplotlib 进行实时绘图

python - 如何从 python 中的 shapefile 绘制虚线?