Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 294
otmezger Avatar asked Nov 21 '13 15:11

otmezger


People also ask

How do I change the width of a line in Matplotlib?

matplotlib.pyplot.plot(x, y, linewidth=1.5) By default, the line width is 1.5 but you can adjust this to any value greater than 0.

How do I change the size of a bar in Python?

Here we'll use the figsize() method to change the bar plot size. Import matplotlib. pyplot library. To change the figure size, use figsize argument and set the width and the height of the plot.


2 Answers

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

like image 198
Warren Weckesser Avatar answered Oct 06 '22 00:10

Warren Weckesser


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.

like image 35
otmezger Avatar answered Oct 05 '22 22:10

otmezger