otmezger
otmezger

Reputation: 10794

python + matplotlib: how can I change the bar's line width for a single bar?

I have a bar plot consisting in 3 stacked series and 5 bars. I want to highlight one single bar (all 3 stacked elements) by changing the width of the line.

I'm drawing the bars with the following command:

mybar = ax.bar(x,Y[:,i],bottom=x,color=colors[i],edgecolor='none',width=wi,linewidth = 0)
bar_handles = np.append(bar_handles,mybar)

I have handle for the bar I want to change stored in the array bar_handles, is there a way to change a bar's edgecolor and linewidth property after it has been drawn?

Upvotes: 8

Views: 26794

Answers (2)

otmezger
otmezger

Reputation: 10794

I ended up doing it like this:

ax.axvspan(X1,
           X1+wi,
           ymax=Y2,
           facecolor='none',
           edgecolor='black',
           linewidth=2)

…where

X1 = bar_handles[startBlock].get_x()
wi = bar_handles[startBlock].get_width()
Y2 = ax.transLimits.transform((0,bar_handles[startBlock].get_height()))[1]

This produces an edge over my bar — including all the elements within — without the horizontal like between the elements.

Upvotes: 4

Warren Weckesser
Warren Weckesser

Reputation: 114976

ax.bar returns a Container of artists; each "artist" is a Rectangle with set_linewidth and set_edgecolor methods.

To change the settings of, say, the second bar in mybar, you could do this:

mybar[1].set_linewidth(4)
mybar[1].set_edgecolor('r')

Here's a script that shows how this could be used to change the linewidth of a stack:

import numpy as np
import matplotlib.pyplot as plt


x = np.array([1,2,3])
y1 = np.array([3,2.5,1])
y2 = np.array([4,3,2])
y3 = np.array([1,4,1])

width = 0.5
handles = []
b1 = plt.bar(x, y1, color='#2040D0', width=width, linewidth=0)
handles.append(b1)
b2 = plt.bar(x, y2, bottom=y1, color='#60A0D0', width=width, linewidth=0)
handles.append(b2)
b3 = plt.bar(x, y3, bottom=y1+y2, color='#A0D0D0', width=width, linewidth=0)
handles.append(b3)

# Highlight the middle stack.
for b in handles:
    b[1].set_linewidth(3)

plt.xlim(x[0]-0.5*width, x[-1]+1.5*width)
plt.xticks(x+0.5*width, ['A', 'B', 'C'])
plt.show()

This script creates the following bar chart:

stacked bar chart

Upvotes: 10

Related Questions