I've seen plenty of examples online of x-axis alignment for matplotlib Table with charts, but I can't figure out how to y-axis align my table. The following code produces the table pictured after it.
# For minimum viable example
dfx = [['ARS FX', 0.025346713729, 0.028238, 0.021889, 0.07701426, 0.0, 35, 39, '14.7%', 0.0, 0.07701426], ['BRL FX',1.83316130513e-05,0.025746,-0.072473, 0.143642325, 0.0, 40, 45, '12.3%', 0.0, 0.143642325], ['EUR FX', -0.301254060209, -0.300762, -0.290554, 0.0, -0.30127866, -60, -40, '5.2%', -0.30127866, 0.0], ['ZAR FX', 0.0515621470331, 0.053191, 0.044245, 0.07344438, 0.0, 10, 29, '14.1%', 0.0, 0.07344438], ['AR Eqity', 3.68762762118e-06, 0.0,0.0, 0.08817912, 0.0, 45, 45, '23.9%', 0.0, 0.08817912]]
dfx = pd.DataFrame(dfx)
dfx.columns = ['IdeaName', 'ModelWeight', 'Exposure_FXA', 'Exposure','Adj_Ubound', 'Adj_Lbound', 'lt_rob', 'st_rob', 'implied_vol', 'Lower Bound', 'Upper Bound']
# Plot
_, ax = plt.subplots()
dfx[['Lower Bound']].plot(kind='barh',ax=ax,color='red')
dfx[['Upper Bound']].plot(kind='barh',ax=ax,color='green')
plt.plot(dfx['ModelWeight'],range(len(dfx)), linestyle="", markersize=5, marker="o", color="#ff6600", label="ModelWeight", markeredgecolor="k")
plt.plot(dfx['Exposure'],range(len(dfx)), linestyle="", markersize=5, marker="o", color='lightblue', label="Exposure", markeredgecolor="k")
# Add a table at the bottom of the axes
columns = ['LT','ST','Vol']
the_table = ax.table(cellText=dfx[['lt_rob','st_rob','implied_vol']].values,
rowLabels=list(dfx['IdeaName']),
# rowColours=colors,
colWidths=[0.1 for x in columns],
colLabels=columns,
cellLoc='center',
loc=15)
the_table.auto_set_font_size(False)
the_table.set_fontsize(9)
the_table.scale(1, 1.05)
plt.subplots_adjust(left=0.4)
plt.yticks([])
plt.legend()
plt.show()
As you can see, despite me manually playing with the_table.scale() to get it as close as possible, I can't get the rows aligned with my bars, since the column headers of the table are taking up the first row.
Any help appreciated. Thanks.
The following would put the table into a bounding box that is one nth larger than the number of bars n. One then needs to make sure the margins within the axes are correct as well as the subplot parameter. The below only adjusts the vertical direction (the horizontal direction needs to be done by hand for longer labels).
import numpy as np
import matplotlib.pyplot as plt
data = np.random.randint(1,999,size=(10,4))
col = list("ABCD")
row = np.arange(1, len(data)+1)
n = len(data) # number of bars
barwidth = 0.8 # bar width
t = 0.05
b = 0.125
# Plot
fig, ax = plt.subplots()
fig.subplots_adjust(left=0.4, top=1-t-(1-t-b)/(n+1))
ax.margins(y=(1-barwidth)/2/n)
ax.barh(row, data[:,0], height=barwidth, label="bars", )
the_table = ax.table(cellText=data,
rowLabels=row,
colLabels=col,
cellLoc='center',
bbox=(-0.6, 0.0, 0.6, (n+1) / n))
the_table.auto_set_font_size(False)
the_table.set_fontsize(9)
fig.canvas.draw() # need to draw the figure twice
plt.yticks([])
plt.legend()
plt.show()
Related
I am trying to rotate the radial tick labels on the attached plot.
Why does matplotlib not rotate them when I have the 'rotation' command specified?
I would then like to shift the labels in the radial direction. Is there an equivalent of the 'pad' command with the polar charts?
import numpy as np
import matplotlib.pyplot as plt
import math
Graph_title = "Radar Plot"
def radarplot():
ax = plt.subplot(111, polar=True)
# INPUT DATA
n_directions = 12
angles = [n / float(n_directions) * 2 * math.pi for n in range(n_directions)]
data = [3.0, 3.0, 3.0, 3.0, 2.0, 2.5, 2.5, 2.5, 2.75, 2.75, 3.0, 3.0]
# Add the last element of the list to the list. This is necessary or the line from 330 deg to 0 degree does not join up on the plot.
angles = np.append(angles, angles[:1])
data = np.append(data, data[:1])
ax.plot(angles, data, linewidth=2, linestyle='solid', color = 'red')
# Radial tick parameters
radial_ticks = [0.00, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00]
ax.set_rlabel_position(45)
ax.set_rorigin(0)
plt.yticks(radial_ticks, color='black', size=8)
ax.set_yticklabels(radial_ticks, rotation = 45, zorder = 500)
# X Tick parameters
plt.xticks(angles, color='black', size=10, zorder = 5)
ax.tick_params(axis='x', which='major', pad=3)
ax.set_theta_zero_location("N") # Sets the labels initial position to 0 degrees
ax.set_theta_direction("clockwise") # Set the labels to rotate clockwise
plt.savefig(Graph_title +".png", figsize = [6.4, 5], dpi=1000)
plt.show()
plt.close()
radarplot()
Recently I wanted to achieve the same thing as you and here is the solution that I came up with.
Suppress the automatic r tick labels using the command ax.set_yticklabels([])
For each radial tick define a tick list, a position list, and an alignment list.
Using the text command write the values in the tick list at the radial locations specified by the position list with alignment specified by the alignment list.
Essentially the r ticks can be moved along the radial direction by changing the values in the position list.
Make sure that the text command is specified with transform=ax.transData option.
import numpy as np
import matplotlib.pyplot as plt
import math
Graph_title = "Radar Plot"
def radarplot():
ax = plt.subplot(111, polar=True)
# INPUT DATA
n_directions = 12
angles = [n / float(n_directions) * 2 * math.pi for n in range(n_directions)]
data = [3.0, 3.0, 3.0, 3.0, 2.0, 2.5, 2.5, 2.5, 2.75, 2.75, 3.0, 3.0]
# Add the last element of the list to the list. This is necessary or the line from 330 deg to 0 degree does not join up on the plot.
angles = np.append(angles, angles[:1])
data = np.append(data, data[:1])
ax.plot(angles, data, linewidth=2, linestyle='solid', color = 'red')
r_ticks = [0.00, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00] #tick list
r_ticks_pos = [0.20, 0.65, 1.15, 1.65, 2.15, 2.65, 3.25] #radial position list (CHANGE THESE VALUES TO MOVE EACH TICK RADIALLY INDIVIDUALLY)
r_ticks_h_align = ['center','center','center','center','center','center','center'] #horizontal alignment list
r_ticks_v_align = ['center','center','center','center','center','center','center'] #vertical alignment list
r_label_angle = 45 #theta angle
# Radial tick parameters
ax.set_rlabel_position(r_label_angle)
ax.set_rorigin(0)
ax.set_yticklabels([])
ax.set_rticks(r_ticks)
ax.set_rlabel_position(r_label_angle)
#write the ticks using the text command
for rtick, rtick_pos, rtick_ha, rtick_va in zip(r_ticks, r_ticks_pos, r_ticks_h_align, r_ticks_v_align):
plt.text(np.radians(r_label_angle), rtick_pos, r'$'+str(rtick)+'$', ha=rtick_ha, va=rtick_va, transform=ax.transData, rotation=-45, fontsize=8)
# X Tick parameters
plt.xticks(angles, color='black', size=10, zorder = 5)
ax.tick_params(axis='x', which='major', pad=3)
ax.set_theta_zero_location("N") # Sets the labels initial position to 0 degrees
ax.set_theta_direction("clockwise") # Set the labels to rotate clockwise
plt.savefig(Graph_title +".png", figsize = [6.4, 5], dpi=1000)
plt.show()
plt.close()
radarplot()
And the result:
I meet the same problem, and I only solved the rotation problem. axis='x' failed to control the rotation, only axis='both' can work.
ax.tick_params(
axis='both',
labelrotation=-45.,
)
I am trying to solve the pad problem.
I'm trying to plot some data and want to have a colored background depending on data.
In the following sample I want to have data1 and data2 on the left yaxis and data3 on right yaxis. This is working. But additionally I tried to colorize the background depending on data3.
How do I need to format the data to get it working?
import matplotlib.pyplot as plt
from datetime import datetime as dt
import matplotlib.dates as md
fig, ax1 = plt.subplots(constrained_layout=True)
data1 = [51.2, 51.2, 51.2, 50.7, 50.7, 50.5, 50.4, 50.7, 50.6]
data2 = [46.5, 46.1, 46.2, 46.3, 46.4, 46.3, 46.2, 46.1, 45.5]
data3 = [ 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]
timestamps = [1524614516, 1524615134, 1524615587, 1524615910, 1524616235, 1524616559, 1524616866, 1524617189, 1524617511]
timestamps_ = [dt.utcfromtimestamp(x) for x in timestamps]
for data in (data1,data2):
ax1.plot(timestamps_, data, marker='.', linestyle='-')
ax1.set_ylabel("degC")
ax2 = ax1.twinx()
ax2.plot(timestamps_, data3, marker='x', linestyle='-')
ax2.pcolor(ax2.get_xlim(), ax2.get_ylim(), zip(timestamps_, data3), cmap='RdGn', alpha=0.3)
ax2.set_ylabel("ON OFF")
ax1.set_title("Mytitle")
for tick in ax1.xaxis.get_major_ticks():
tick.label1.set_horizontalalignment('right')
tick.label1.set_rotation(35)
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax1.xaxis.set_major_formatter(xfmt)
plt.show()
Error message:
Traceback (most recent call last):
File "/home/tobias/workspace/python_pyplot_test/main.py", line 25, in <module>
ax2.pcolor(ax2.get_xlim(), ax2.get_ylim(), zip(timestamps_, data3), cmap='RdGn', alpha=0.3)
File "/usr/local/lib/python2.7/dist-packages/matplotlib/__init__.py", line 1855, in inner
return func(ax, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_axes.py", line 5732, in pcolor
X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_axes.py", line 5576, in _pcolorargs
C.shape, Nx, Ny, funcname))
TypeError: Dimensions of C (9, 2) are incompatible with X (2) and/or Y (2); see help(pcolor)
Here's a minimal solution to what you want:
import matplotlib.pyplot as plt
from datetime import datetime as dt
import matplotlib.dates as md
import numpy as np
data3 = np.array([ 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0])
x=np.arange(9)
xp,yp=np.meshgrid(x,data3)
xp=xp.astype(float)-0.5
bgcolor=np.ones(xp.shape)*data3[None,:]
plt.pcolor(xp,yp,bgcolor)
plt.plot(x, data3, marker='x', linestyle='-')
I took out the second axis and all the tick stuff as they were not related to the problem itself.
Another option is to use axvspans:
One difference between using axvspan and pcolor is that the vertical span (rectangles) drawn by axvspan are unbounded in the y-direction while the pcolor rectangles are not. So if you use the zoom button to resize the plot, the axvspan rectangles will stretch to infinity (roughly speaking) while zooming out the pcolor rectangles will expose white areas. It's not a big deal, just thought you'd like to know.
Also note that if the vertical spans start at the first data point and extend to the next data point, then the last value in data3 never gets used. (Nine data points make eight vertical spans). If, however, you center the vertical spans around the data points -- so each data point is in the center of a span, then all 9 values in data3 can be used.
Uncomment the commented code below (and comment-out the current definition of timestamps_left and timestamps_right) to see the difference.
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime as dt
import matplotlib.dates as md
def topydates(timestamps):
return [dt.utcfromtimestamp(x) for x in timestamps]
fig, ax1 = plt.subplots(constrained_layout=True)
data1 = [51.2, 51.2, 51.2, 50.7, 50.7, 50.5, 50.4, 50.7, 50.6]
data2 = [46.5, 46.1, 46.2, 46.3, 46.4, 46.3, 46.2, 46.1, 45.5]
data3 = [ 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
timestamps = np.array([1524614516, 1524615134, 1524615587, 1524615910,
1524616235, 1524616559, 1524616866, 1524617189, 1524617511])
timestamps_ = topydates(timestamps)
for data in (data1,data2):
ax1.plot(timestamps_, data, marker='.', linestyle='-')
ax1.set_ylabel("degC")
ax2 = ax1.twinx()
ax2.plot(timestamps_, data3, marker='x', linestyle='-')
# if you want the axvspans to be centered around the data points
# widths = np.diff(timestamps)
# midpoints = timestamps[:-1] + widths/2.0
# timestamps_left = topydates(np.r_[timestamps[0]-widths[0]/2, midpoints])
# timestamps_right = topydates(np.r_[midpoints, timestamps[-1] + widths[-1]/2.0])
# if you uncomment the code above, then comment-out the line below:
timestamps_left, timestamps_right = timestamps_[:-1], timestamps_[1:]
cmap = plt.get_cmap('RdYlGn')
for left, right, val in zip(timestamps_left, timestamps_right, data3):
print(left, right)
color = cmap(val)
ax2.axvspan(left, right, facecolor=color, alpha=0.3)
ax2.set_ylabel("ON OFF")
ax1.set_title("Mytitle")
for tick in ax1.xaxis.get_major_ticks():
tick.label1.set_horizontalalignment('right')
tick.label1.set_rotation(35)
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax1.xaxis.set_major_formatter(xfmt)
plt.show()
Wondering if its possible to create subplots of a subplot. The reason I am looking to do this is to create 3 broken axis charts on a single plot. I understand how to create a single broken axis chart with the example code below, but since a broken axis chart requires the use of subplots I am now in a position where I am trying to use subplots to create 3 columns, then subplot those columns into a subplot with 2 rows to create the broken axis chart. See below for visual explanation.
"""
EXAMPLE OF A SINGLE BROKEN AXIS CHART
"""
import matplotlib.pyplot as plt
import numpy as np
# 30 points between 0 0.2] originally made using np.random.rand(30)*.2
ptsA = np.array([
0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018,
0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075,
0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008])
# Now let's make two outlier points which are far away from everything.
ptsA[[3, 14]] += .8
# 30 points between 0 0.2] originally made using np.random.rand(30)*.2
ptsB = np.array([
0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018,
0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075,
0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008])
# Now let's make two outlier points which are far away from everything.
ptsB[[1, 7, 9, 13, 15]] += .95
# If we were to simply plot pts, we'd lose most of the interesting
# details due to the outliers. So let's 'break' or 'cut-out' the y-axis
# into two portions - use the top (ax) for the outliers, and the bottom
# (ax2) for the details of the majority of our data
f, (ax, ax2) = plt.subplots(2, 1, sharex=True)
# plot the same data on both axes
ax.plot(ptsB)
ax2.plot(pts)
# zoom-in / limit the view to different portions of the data
ax.set_ylim(.78, 1.) # outliers only
ax2.set_ylim(0, .22) # most of the data
# hide the spines between ax and ax2
ax.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax.xaxis.tick_top()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.xaxis.tick_bottom()
# This looks pretty good, and was fairly painless, but you can get that
# cut-out diagonal lines look with just a bit more work. The important
# thing to know here is that in axes coordinates, which are always
# between 0-1, spine endpoints are at these locations (0,0), (0,1),
# (1,0), and (1,1). Thus, we just need to put the diagonals in the
# appropriate corners of each of our axes, and so long as we use the
# right transform and disable clipping.
d = .015 # how big to make the diagonal lines in axes coordinates
# arguments to pass plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal
kwargs.update(transform=ax2.transAxes) # switch to the bottom axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal
# What's cool about this is that now if we vary the distance between
# ax and ax2 via f.subplots_adjust(hspace=...) or plt.subplot_tool(),
# the diagonal lines will move accordingly, and stay right at the tips
# of the spines they are 'breaking'
plt.show()
Desired Output
3 subplots, each containing 2 subplots
First of all you cannot create a subplot of a subplot. Subplots are axes objects placed in a figure and an axes cannot have "child axes".
The solution to your problem would be to create 6 subplots and apply sharex=True to the respective axes.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(17, 6)
data[15:, 3:] = np.random.rand(2, 3)+3.
markers=["o", "p", "s"]
colors=["r", "g", "b"]
fig=plt.figure(figsize=(10, 4))
axes = []
for i in range(3):
ax = fig.add_subplot(2,3,i+1)
axes.append(ax)
for i in range(3):
ax = fig.add_subplot(2,3,i+4, sharex=axes[i])
axes.append(ax)
for i in range(3):
# plot same data in both top and down axes
axes[i].plot(data[:,i], data[:,i+3], marker=markers[i], linestyle="", color=colors[i])
axes[i+3].plot(data[:,i], data[:,i+3], marker=markers[i], linestyle="", color=colors[i])
for i in range(3):
axes[i].spines['bottom'].set_visible(False)
axes[i+3].spines['top'].set_visible(False)
axes[i].xaxis.tick_top()
axes[i].tick_params(labeltop='off') # don't put tick labels at the top
axes[i+3].xaxis.tick_bottom()
axes[i].set_ylim([3,4])
axes[i+3].set_ylim([0,1])
axes[i].set_xlim([0,1])
#adjust space between subplots
plt.subplots_adjust(hspace=0.08, wspace=0.4)
plt.show()
Wondering if its possible to create subplots of a subplot. The reason I am looking to do this is to create 3 broken axis charts on a single plot. I understand how to create a single broken axis chart with the example code below, but since a broken axis chart requires the use of subplots I am now in a position where I am trying to use subplots to create 3 columns, then subplot those columns into a subplot with 2 rows to create the broken axis chart. See below for visual explanation.
"""
EXAMPLE OF A SINGLE BROKEN AXIS CHART
"""
import matplotlib.pyplot as plt
import numpy as np
# 30 points between 0 0.2] originally made using np.random.rand(30)*.2
ptsA = np.array([
0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018,
0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075,
0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008])
# Now let's make two outlier points which are far away from everything.
ptsA[[3, 14]] += .8
# 30 points between 0 0.2] originally made using np.random.rand(30)*.2
ptsB = np.array([
0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018,
0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075,
0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008])
# Now let's make two outlier points which are far away from everything.
ptsB[[1, 7, 9, 13, 15]] += .95
# If we were to simply plot pts, we'd lose most of the interesting
# details due to the outliers. So let's 'break' or 'cut-out' the y-axis
# into two portions - use the top (ax) for the outliers, and the bottom
# (ax2) for the details of the majority of our data
f, (ax, ax2) = plt.subplots(2, 1, sharex=True)
# plot the same data on both axes
ax.plot(ptsB)
ax2.plot(pts)
# zoom-in / limit the view to different portions of the data
ax.set_ylim(.78, 1.) # outliers only
ax2.set_ylim(0, .22) # most of the data
# hide the spines between ax and ax2
ax.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax.xaxis.tick_top()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.xaxis.tick_bottom()
# This looks pretty good, and was fairly painless, but you can get that
# cut-out diagonal lines look with just a bit more work. The important
# thing to know here is that in axes coordinates, which are always
# between 0-1, spine endpoints are at these locations (0,0), (0,1),
# (1,0), and (1,1). Thus, we just need to put the diagonals in the
# appropriate corners of each of our axes, and so long as we use the
# right transform and disable clipping.
d = .015 # how big to make the diagonal lines in axes coordinates
# arguments to pass plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal
kwargs.update(transform=ax2.transAxes) # switch to the bottom axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal
# What's cool about this is that now if we vary the distance between
# ax and ax2 via f.subplots_adjust(hspace=...) or plt.subplot_tool(),
# the diagonal lines will move accordingly, and stay right at the tips
# of the spines they are 'breaking'
plt.show()
Desired Output
3 subplots, each containing 2 subplots
First of all you cannot create a subplot of a subplot. Subplots are axes objects placed in a figure and an axes cannot have "child axes".
The solution to your problem would be to create 6 subplots and apply sharex=True to the respective axes.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(17, 6)
data[15:, 3:] = np.random.rand(2, 3)+3.
markers=["o", "p", "s"]
colors=["r", "g", "b"]
fig=plt.figure(figsize=(10, 4))
axes = []
for i in range(3):
ax = fig.add_subplot(2,3,i+1)
axes.append(ax)
for i in range(3):
ax = fig.add_subplot(2,3,i+4, sharex=axes[i])
axes.append(ax)
for i in range(3):
# plot same data in both top and down axes
axes[i].plot(data[:,i], data[:,i+3], marker=markers[i], linestyle="", color=colors[i])
axes[i+3].plot(data[:,i], data[:,i+3], marker=markers[i], linestyle="", color=colors[i])
for i in range(3):
axes[i].spines['bottom'].set_visible(False)
axes[i+3].spines['top'].set_visible(False)
axes[i].xaxis.tick_top()
axes[i].tick_params(labeltop='off') # don't put tick labels at the top
axes[i+3].xaxis.tick_bottom()
axes[i].set_ylim([3,4])
axes[i+3].set_ylim([0,1])
axes[i].set_xlim([0,1])
#adjust space between subplots
plt.subplots_adjust(hspace=0.08, wspace=0.4)
plt.show()
How do I exactly specify the colorbar labels in matplotlib? Frequently, I need to create very specific color scales, but the colorbar labels display so poorly you can't tell what the scale is. I would like to manually define the text next to the colorbar tick marks, or at least have them display in scientific notation.
Here is an example plot where you can't tell what the bottom four color bins represent:
And here is a working example of how that plot was created:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
# mock up some data
x = np.random.random(50)
y = np.random.random(50)
c = np.arange(0, 1, 1.0/50.0) # color of points
c[0] = 0.00001
c[1] = 0.0001
c[2] = 0.001
c[3] = 0.01
s = 500 * np.random.random(50) + 25 # size of points
# set up some custom color scaling
lcmap = colors.ListedColormap(['#FFFFFF', '#FF99FF', '#8000FF',
'#0000FF', '#0080FF', '#58FAF4',
'#00FF00', '#FFFF00', '#FF8000',
'#FF0000'])
bounds = [0.0, 0.000001, 0.00001, 0.0001,
0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 1.0]
norm = colors.BoundaryNorm(bounds, lcmap.N)
# create some plot
fig, ax = plt.subplots()
im = ax.scatter(x, y, c=c, s=s, cmap=lcmap, norm=norm)
# add the colorbar
fig.colorbar(im, ax=ax)
fig.savefig('temp.jpg')
cbar = fig.colorbar(cax, ticks=[-1, 0, 1])
cbar.ax.set_xticklabels(['Low', 'Medium', 'High'])
and use whatever iterable you want instead of ['Low', 'Medium', 'High']
see: http://matplotlib.org/examples/pylab_examples/colorbar_tick_labelling_demo.html