Based on this question about heatmaps in matplotlib, I wanted to move the x-axis titles to the top of the plot.
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.set_label_position('top') # <-- This doesn't work!
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()
However, calling matplotlib's set_label_position (as notated above) doesn't seem to have the desired effect. Here's my output:
What am I doing wrong?
Use
ax.xaxis.tick_top()
to place the tick marks at the top of the image. The command
ax.set_xlabel('X LABEL')
ax.xaxis.set_label_position('top')
affects the label, not the tick marks.
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
You want set_ticks_position rather than set_label_position:
ax.xaxis.set_ticks_position('top') # the rest is the same
This gives me:
tick_params is very useful for setting tick properties. Labels can be moved to the top with:
ax.tick_params(labelbottom=False,labeltop=True)
You've got to do some extra massaging if you want the ticks (not labels) to show up on the top and bottom (not just the top). The only way I could do this is with a minor change to unutbu's code:
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.xaxis.set_ticks_position('both') # THIS IS THE ONLY CHANGE
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
Output:
Related
Based on this question about heatmaps in matplotlib, I wanted to move the x-axis titles to the top of the plot.
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.set_label_position('top') # <-- This doesn't work!
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()
However, calling matplotlib's set_label_position (as notated above) doesn't seem to have the desired effect. Here's my output:
What am I doing wrong?
Use
ax.xaxis.tick_top()
to place the tick marks at the top of the image. The command
ax.set_xlabel('X LABEL')
ax.xaxis.set_label_position('top')
affects the label, not the tick marks.
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
You want set_ticks_position rather than set_label_position:
ax.xaxis.set_ticks_position('top') # the rest is the same
This gives me:
tick_params is very useful for setting tick properties. Labels can be moved to the top with:
ax.tick_params(labelbottom=False,labeltop=True)
You've got to do some extra massaging if you want the ticks (not labels) to show up on the top and bottom (not just the top). The only way I could do this is with a minor change to unutbu's code:
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.xaxis.set_ticks_position('both') # THIS IS THE ONLY CHANGE
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
Output:
Here I plot a bar graph and a line graph in the same figure:
There are 2 y-axes, money and increase_rate, each on a different scale.
How can I set the ticks of the two y-axes to be at the same hight?
import numpy as np
import matplotlib.pyplot as plt
time = [2000,2001,2002,2003]
money = [1000,2000,4000,6000]
increase_rate =[2,1,6,12]
fig, ax1 = plt.subplots()
width = 0.75
ax1.set_xlabel("")
ax1.set_ylabel("")
ax1.bar(time, money ,width = width, color = "#9370DB", alpha=0.6)
ax1.tick_params(axis='y')
ax1.spines['right'].set_visible(False)
ax1.spines['left'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax1.spines['bottom'].set_visible(False)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.set_ylabel("")
ax2.plot(time, increase_rate, color = "#FFFF00", lw = 3)
ax2.tick_params(axis='y')
ax2.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax2.grid(color='black', linestyle='dotted', linewidth=0.8, alpha = 0.5)
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
Use the set_yticks to set the tick positions.
ax1.set_yticks(np.linspace(0, max(money), 5))
ax2.set_yticks(np.linspace(0, max(increase_rate), 5))
To keep the colorbar aspect in subplot using cartopy, I insert new axis (add_axes) im my plot, but in adding, I need change the size of ticklabels colorbar and bold. But tick_params and set_yticklabels in not working in new axes.
# pos x, pos y, size x, size y
cb_ax = fig.add_axes([0.91, 0.302, 0.015, 0.383])
bar = fig.colorbar(img, cax=cb_ax, extend='max',
shrink=0.8, pad=0.0, spacing='uniform',
orientation='vertical', ticks=clevs,
extendfrac='auto')
bar.set_label(label=f'(mm)', size=10, weight='bold')
# not working
# bar.tick_params(labelsize=10)
# not working
# bar.img.set_yticklabels(clevs, fontsize=9, weight='bold')
Entire code: https://pastebin.com/NfiMWf2n
Plot result: https://1drv.ms/u/s!Amb6LUmV4LnKi55gRf6DqGDKjfTGxA?e=HCGeZb
You can set the weight and fontsize of bar.ax:
import matplotlib.pyplot as plt
import numpy as np
fig=plt.figure()
img = plt.imshow(np.random.random((4,4)))
cb_ax = fig.add_axes([0.91, 0.302, 0.015, 0.383])
bar = fig.colorbar(img, cax=cb_ax, extend='max',
shrink=0.8, pad=0.0, spacing='uniform',
orientation='vertical',
extendfrac='auto')
fig.canvas.flush_events() #else bar.ax.get_yticklabels() is not yet updated
bar.ax.set_yticklabels(labels=bar.ax.get_yticklabels(), weight='bold', fontsize=5)
bar.set_label(label=f'(mm)', size=10, weight='bold')
Output:
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.set_label_position('top') # <-- This doesn't work!
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()
Above code is from: Moving x-axis to the top of a plot in matplotlib
How can I change output from this script so that it looks aesthetically more like this picture:
Any solution using python matplotlib or seaborn works. I want to insert white between the cells, have the cells be square and also control their size
I think you need 2 tricks. First, add the line
ax.set_aspect('equal')
to make the cells appear as squares (assuming that you have an equal number on the x- and y-axes, as in your example). If you have x squares on the x-axis and y squares on the y-axis, I suspect that you could instead do,
ax.set_aspect(float(y) / float(x))
Second, you need to add edgecolor to the cells and make the edges thick, so modify your line to e.g.,
heatmap = ax.pcolor(data, cmap=plt.cm.Blues, edgecolor='white', linewidths=10)
The result is
I'd like to create a colorbar legend for a heatmap, such that the labels are in the center of each discrete color. Example borrowed from here:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
#discrete color scheme
cMap = ListedColormap(['white', 'green', 'blue','red'])
#data
np.random.seed(42)
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=cMap)
#legend
cbar = plt.colorbar(heatmap)
cbar.ax.set_yticklabels(['0','1','2','>3'])
cbar.set_label('# of contacts', rotation=270)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
ax.invert_yaxis()
#labels
column_labels = list('ABCD')
row_labels = list('WXYZ')
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
This generates the following plot:
Ideally I'd like to generate a legend bar which has the four colors and for each color, a label in its center: 0,1,2,>3. How can this be achieved?
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
#discrete color scheme
cMap = ListedColormap(['white', 'green', 'blue','red'])
#data
np.random.seed(42)
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=cMap)
#legend
cbar = plt.colorbar(heatmap)
cbar.ax.get_yaxis().set_ticks([])
for j, lab in enumerate(['$0$','$1$','$2$','$>3$']):
cbar.ax.text(.5, (2 * j + 1) / 8.0, lab, ha='center', va='center')
cbar.ax.get_yaxis().labelpad = 15
cbar.ax.set_ylabel('# of contacts', rotation=270)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)
ax.invert_yaxis()
#labels
column_labels = list('ABCD')
row_labels = list('WXYZ')
ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
You were very close. Once you have a reference to the color bar axis, you can do what ever you want to it, including putting text labels in the middle. You might want to play with the formatting to make it more visible.
To add to tacaswell's answer, the colorbar() function has an optional cax input you can use to pass an axis on which the colorbar should be drawn. If you are using that input, you can directly set a label using that axis.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots()
heatmap = ax.imshow(data)
divider = make_axes_locatable(ax)
cax = divider.append_axes('bottom', size='10%', pad=0.6)
cb = fig.colorbar(heatmap, cax=cax, orientation='horizontal')
cax.set_xlabel('data label') # cax == cb.ax
This will make you add label and change colorbar's tick and label size:
clb=plt.colorbar()
clb.ax.tick_params(labelsize=8)
clb.ax.set_title('Your Label',fontsize=8)
This can be also used if you have sublots:
plt.tight_layout()
plt.subplots_adjust(bottom=0.05)
cax = plt.axes([0.1, 0, 0.8, 0.01]) #Left,bottom, length, width
clb=plt.colorbar(cax=cax,orientation="horizontal")
clb.ax.tick_params(labelsize=8)
clb.ax.set_title('Your Label',fontsize=8)