python - 颜色并不一致地应用于子图中的类别

标签 python pandas matplotlib

有了以下代码,我无法理解为什么没有正确显示信息(检查 C 和 F 列)机器人显示为相同的值但不同

我需要的是绘制 df 中的一些列并在所有子图之间共享图例 (所有列具有相同的值 ["SI","NO"] (这只是示例代码)

colnames=['a','b','c','d','e','f','g']
values=[
    ['SI','SI','NO','SI','SI','SI','NO'],
    ['SI','NO','NO','SI','NO','SI','NO'],
    ['SI','SI','NO','SI','SI','SI','NO'],
    ['SI','NO','NO','NO','NO','SI','SI'],
    ['SI','NO','NO','NO','NO','SI','NO']]

df=pd.DataFrame(values, columns=colnames)

def pieplotstest(df):
    fig,ax =plt.subplots(2,3,facecolor=(1, 1, 1),figsize=(7.2,4.3))
    plt.style.use('fivethirtyeight')

    colors=["#172a3d","#e33e31"]
    textprops=dict(color="w",weight='bold',size=5)
    labels=['NO','SI']

    ax[0,0].pie(df['b'].value_counts(),
            colors=colors,
            autopct = '%1.1f%%',
            textprops=textprops,
            wedgeprops=dict(width=0.5),
            pctdistance=0.7
        )
    ax[0,1].pie(df['c'].value_counts(),
            colors=colors,
            autopct = '%1.1f%%',
            textprops=textprops,
            wedgeprops=dict(width=0.5),
            pctdistance=0.75

        )
    ax[0,2].pie(df['d'].value_counts(),
            colors=colors,
            autopct = '%1.1f%%',
            textprops=textprops,
            wedgeprops=dict(width=0.5),
            pctdistance=0.75
        )
    ax[1,0].pie(df['e'].value_counts(),
            colors=colors,
            autopct = '%1.1f%%',
            textprops=textprops,
            wedgeprops=dict(width=0.5),
            pctdistance=0.75
        )
    ax[1,1].pie(df['f'].value_counts(),
            colors=colors,
            autopct = '%1.1f%%',
            textprops=textprops,
            wedgeprops=dict(width=0.5),
            pctdistance=0.75
        )
    ax[1,2].pie(df['g'].value_counts(),
            colors=colors,
            autopct = '%1.1f%%',
            textprops=textprops,
            wedgeprops=dict(width=0.5),
            pctdistance=0.75
        )

    ax[0,0].set_title('b',fontsize=10)
    ax[0,1].set_title('c',fontsize=10)
    ax[0,2].set_title('d',fontsize=10)
    ax[1,0].set_title('e',fontsize=10)
    ax[1,1].set_title('f',fontsize=10)
    ax[1,2].set_title('g',fontsize=10)
    fig.legend(labels,
            loc=4,                
            fontsize=7
            )
    plt.suptitle('Como estan distribuidas tus ventas')
    fig.tight_layout()
    plt.savefig(f'orders3.png',dpi=600,transparent=True)

结果是: enter image description here

最佳答案

  • 如果直接使用 pandas.DataFrame.plot.pie 绘制数据框,那么颜色就会得到妥善管理。
    • 选择要绘制的特定列:dfc[['b', 'c', 'd', 'e', 'f', 'g']].plot.pie(...)
  • 使用.melt将数据帧从宽转换为长
  • 使用pd.crosstab获取每组的值计数
    • dfc 显示所有值,即使是 0,与使用 .value_counts() 不同。这将确保每个组始终正确应用颜色。
  • 使用 autopct='%1.1f%%'autopct = lambda v: f'{v:.1f}%' if v > 0 else None 来设置楔形标签的格式。第二个选项不会添加标签,除非值为 >0
# display(dfc)
variable  a  b  c  d  e  f  g
value                        
NO        0  3  5  2  3  0  4
SI        5  2  0  3  2  5  1
  • 这会消除冗余,从而大大减少您的代码库
  • pandas 1.3.2matplotlib 3.4.2 中测试
import pandas as pd
from matplotlib.patches import Patch

# used df from the OP

def pieplotstest(df):
    colors=["#172a3d", "#e33e31"]
    textprops=dict(color="w", weight='bold', size=9)
    labels=['NO','SI']

    # convert the dataframe from wide to long
    dfm = df.melt()

    # get the counts for each group
    dfc = pd.crosstab(dfm.value, dfm.variable)

    # format the percent value to be None if the value is not greater than 0
    autopct = lambda v: f'{v:.1f}%' if v > 0 else None

    # plot the dataframe directly
    axes = dfc.plot.pie(subplots=True, layout=(2, 4), colors=colors,
                        autopct=autopct, figsize=(10, 6), textprops=textprops,
                        wedgeprops=dict(width=0.5), pctdistance=0.7, legend=False)

    # flatten the array of axes
    axes = axes.ravel()

    # extract the figure object
    fig = axes[0].get_figure()

    # rotate the label
    for ax in axes:
        yl = ax.get_ylabel()
        ax.set_ylabel(yl, rotation=0, fontsize=12)

    # create the legend
    legend_elements = [Patch(fc=c, label=l) for c, l in zip(colors, labels)]
    fig.legend(handles=legend_elements, loc=4, fontsize=12, bbox_to_anchor=(.95, .2))

    fig.tight_layout()
    fig.suptitle('Como estan distribuidas tus ventas')
    fig.savefig(f'orders3.png',dpi=600,transparent=True)


pieplotstest(df)

enter image description here

关于python - 颜色并不一致地应用于子图中的类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68990413/

相关文章:

python - Pandas 数据读取器 : normalizing dates

python-2.7 - 将每个数组的散点移动 delta x

python - 在现有图表之上绘图 Python Matplotlib

python - 在 Python 中读取 Gmail 电子邮件

python - 根据给定的分布对数据帧进行采样

python - Tensorflow "Transformer model for language understanding"与另一个数据集?

python - Pandas DataFrame.hist Seaborn 等价物

python - 使用 matplotlib 在条形图中并排显示多列

python - Cumsum 和矢量化切片

python - "Least Astonishment"和可变默认参数