Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib: How to adjust linewidth in colorbar for contour plot?

Here's a minimal example to generate a plot which illustrates my question:

import matplotlib.pylab as plt
import matplotlib.mpl as mpl
import numpy as np
import random

data = [[random.random() for i in range(10)] for j in range(10)]

[XT, YT] = np.meshgrid(np.arange(1,10+1,1), np.arange(1,10+1,1))

cmap = mpl.cm.gray

fig, ax = plt.subplots()

CS = ax.contour(XT, YT, data,levels=np.arange(0,1+0.1,0.1),\
                cmap=cmap,linewidths=0.75)
CB = plt.colorbar(CS, ticks=np.arange(0,1+0.1,0.1))  

plt.show()

The resulting figure looks like this:

gray_contours

I would like to keep the linewidths of the contour lines in the figure at 0.75 but increase them in the colorbar (for better readability).

How do I change the linewidths in the colorbar without changing them in the figure?

I initially tried CB.collections, but the colorbar has no collections. Also, calling colorbar with an argument linewidths=4.0 does not work (it's an unknown parameter).

Comment
While typing this question I had this idea (rubber duck debugging):

CS = ax.contour(XT, YT, data,levels=np.arange(0,1+0.1,0.1),\
            cmap=cmap,linewidths=4.0)
CB = plt.colorbar(CS, ticks=np.arange(0,1+0.1,0.1))
plt.setp(CS.collections , linewidth=0.75)

Basically, setting the initial linewidths to the desired level for the colorbar, then generating the colorbar and afterwards using collections on the original contour-lines to decrease their linewidth.
This works.

But: Is there a way to directly control the linewidths in the colorbar?

like image 877
Schorsch Avatar asked Oct 14 '13 20:10

Schorsch


1 Answers

You just need to find out how to access those lines, let try:

>>> CB.ax.get_children()
[<matplotlib.axis.XAxis object at 0x026A74B0>, <matplotlib.axis.YAxis object at 0x026AF270>, <matplotlib.lines.Line2D object at 0x026AF190>, <matplotlib.patches.Polygon object at 0x027387F0>, <matplotlib.collections.LineCollection object at 0x02748BD0>, <matplotlib.text.Text object at 0x026C0D10>, <matplotlib.patches.Rectangle object at 0x026C0D50>, <matplotlib.spines.Spine object at 0x026A7410>, <matplotlib.spines.Spine object at 0x026A7290>, <matplotlib.spines.Spine object at 0x026A7350>, <matplotlib.spines.Spine object at 0x026A71B0>]

Alright, take a guess, I bet the 5th item is a list of the divider lines. We are looking for some .line objects and there are two. The first one (3rd item) actually is the edge of the entire color bar (if I remember correctly). So I will go for the next .line object.

Now let's try to modified it in a few ways:

>>> len(lines1[4].get_linewidths())
11 #how many item are there? 11 lines
>>> lines1[4].set_color(['r']*11) #set them all to red, in this example we actually want to have the color stay the same, this is just for a demonstration. 
>>> lines1[4].set_linewidths([2]*11) #set them all to have linewidth of 2.

the resultenter image description here

like image 58
CT Zhu Avatar answered Oct 02 '22 22:10

CT Zhu