在 pandas 中更改箱线图的颜色

Change the facecolor of boxplot in pandas

我需要更改使用 pandas 效用函数绘制的箱线图的颜色。我可以使用 color 参数更改大多数属性,但不知道如何更改框的 facecolor。有人知道怎么做吗?

import pandas as pd
import numpy as np
data = np.random.randn(100, 4)
labels = list("ABCD")
df = pd.DataFrame(data, columns=labels)
props = dict(boxes="DarkGreen", whiskers="DarkOrange", medians="DarkBlue", caps="Gray")
df.plot.box(color=props)

虽然我仍然在 pandas 的绘图界面上推荐 seaborn 和 raw matplotlib,但事实证明你可以将 patch_artist=True 作为 kwarg 传递给 df.plot.box,这将传递它作为 df.plot 的 kwarg,它将作为 matplotlib.Axes.boxplot.

的 kwarg
import pandas as pd
import numpy as np
data = np.random.randn(100, 4)
labels = list("ABCD")
df = pd.DataFrame(data, columns=labels)
props = dict(boxes="DarkGreen", whiskers="DarkOrange", medians="DarkBlue", caps="Gray")
df.plot.box(color=props, patch_artist=True)

按照建议,我最终创建了一个函数来绘制它,使用原始 matplotlib

def plot_boxplot(data, ax):
    bp = ax.boxplot(data.values, patch_artist=True)

    for box in bp['boxes']:
        box.set(color='DarkGreen')
        box.set(facecolor='DarkGreen')

    for whisker in bp['whiskers']:
        whisker.set(color="DarkOrange")

    for cap in bp['caps']:
        cap.set(color="Gray")

    for median in bp['medians']:
        median.set(color="white")

    ax.axhline(0, color="DarkBlue", linestyle=":")

    ax.set_xticklabels(data.columns)

我建议将 df.plot.boxpatch_artist=Truereturn_type='both' 一起使用(returns 绘制箱线图的 matplotlib 轴和一个值为 matplotlib 行的字典箱线图)以获得最佳的定制可能性。

例如,给定此数据:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    data=np.random.randn(100, 4), 
    columns=list("ABCD")
)

您可以为所有方框设置特定颜色:

fig,ax = plt.subplots(figsize=(9,6)) 
ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax)
for patch in props['boxes']:
    patch.set_facecolor('lime')
plt.show()

您可以为每个框设置特定颜色:

colors = ['green','blue','yellow','red']

fig,ax = plt.subplots(figsize=(9,6)) 
ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax)
for patch,color in zip(props['boxes'],colors):
    patch.set_facecolor(color)
plt.show()

您可以轻松集成一个 colormap:

colors = np.random.randint(0,10, 4)
cm = plt.cm.get_cmap('rainbow')
colors_cm = [cm((c-colors.min())/(colors.max()-colors.min())) for c in colors]

fig,ax = plt.subplots(figsize=(9,6)) 
ax,props = df.plot.box(patch_artist=True, return_type='both', ax=ax)
for patch,color in zip(props['boxes'],colors_cm):
    patch.set_facecolor(color)
# to add colorbar
fig.colorbar(plt.cm.ScalarMappable(
    plt.cm.colors.Normalize(min(colors),max(colors)), 
    cmap='rainbow'
), ax=ax, cmap='rainbow')
plt.show()