如何用渐变填充matplotlib栏?

2024-04-29 09:52:42 发布

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

我很有兴趣用不同的梯度填充条形图的matplotlib/seaborn条形图,就像这里所做的那样(据我所知,不是用matplotlib): enter image description here

我还检查了这个相关主题Pyplot: vertical gradient fill under curve?。在

这是否只有通过gr框架才能实现: enter image description here 或者有其他的策略吗?在


Tags: 框架主题matplotlibseabornfill策略兴趣梯度
3条回答

我使用seabornbarplotpalette选项。假设您有一个简单的数据帧,如:

df = pd.DataFrame({'a':[1,2,3,4,5], 'b':[10,5,2,4,5]})

使用seaborn:

^{pr2}$

您可以获得如下内容:

enter image description here

然后您还可以使用palette选项和colormap根据以下数据添加渐变:

sns.barplot(df['a'], df['b'], palette=cm.Blues(df['b']*10)

获得:

enter image description here

希望有帮助。在

正如Pyplot: vertical gradient fill under curve?中所描述的,可以使用图像来创建渐变图。在

由于条形图是矩形的,所以图像的范围可以直接设置为条形图的位置和大小。你可以循环所有的酒吧和创建一个图像在各自的位置。结果是一个渐变条形图。在

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

bar = ax.bar([1,2,3,4,5,6],[4,5,6,3,7,5])

def gradientbars(bars):
    grad = np.atleast_2d(np.linspace(0,1,256)).T
    ax = bars[0].axes
    lim = ax.get_xlim()+ax.get_ylim()
    for bar in bars:
        bar.set_zorder(1)
        bar.set_facecolor("none")
        x,y = bar.get_xy()
        w, h = bar.get_width(), bar.get_height()
        ax.imshow(grad, extent=[x,x+w,y,y+h], aspect="auto", zorder=0)
    ax.axis(lim)

gradientbars(bar)

plt.show() 

enter image description here

我使用Seaborn而不是Matplotlib改编了@ImportanceOfBeingErnest的答案here。在

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

def gradientbars(bars):
    grad = np.atleast_2d(np.linspace(0,1,256)).T # Gradient of your choice

    rectangles = bars.containers[0]
    # ax = bars[0].axes
    fig, ax = plt.subplots()

    xList = []
    yList = []
    for rectangle in rectangles:
        x0 = rectangle._x0
        x1 = rectangle._x1
        y0 = rectangle._y0
        y1 = rectangle._y1

        xList.extend([x0,x1])
        yList.extend([y0,y1])

        ax.imshow(grad, extent=[x0,x1,y0,y1], aspect="auto", zorder=0)

    ax.axis([min(xList), max(xList), min(yList), max(yList)*1.1]) # *1.1 to add some buffer to top of plot

    return fig,ax


sns.set(style="whitegrid", color_codes=True)
np.random.seed(sum(map(ord, "categorical")))

# Load dataset
titanic = sns.load_dataset("titanic")

# Make Seaborn countplot
seabornAxHandle = sns.countplot(x="deck", data=titanic, palette="Greens_d")
plt.show() # Vertical bars with horizontal gradient

# Call gradientbars to make vertical gradient barplot using Seaborn ax
figVerticalGradient, axVerticalGradient = gradientbars(seabornAxHandle)

# Styling using the returned ax
axVerticalGradient.xaxis.grid(False)
axVerticalGradient.yaxis.grid(True)

# Labeling plot to match Seaborn
labels=titanic['deck'].dropna().unique().to_list() # Chaining to get tick labels as a list
labels.sort()
plt.ylabel('count')
plt.xlabel('deck')
plt.xticks(range(0,len(labels)), labels)  # Set locations and labels

plt.show() # Vertical bars with vertical gradient

Seaborn countplot输出: Output from Seaborn countplot

带垂直渐变条的输出: Output with gradient bars

相关问题 更多 >