Issue
I am trying to use a second y-axis to group my y-labels. It somewhat works, but my heatmap is getting cut on the top and bottom and the frame changes when the second axis is added. See the first linked picture below. When the code below "# Adding second y axis" is removed, the second picture below results.
heatmap with second y axis but cut off table
correct heatmap without second y axis
I suspect the line "par2 = ax.twinx() # probably wrong?" to be wrong, but ax.twiny() looks even worse - where is my mistake?
import numpy as np
import matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
vegetables = ["cucumber", "tomato", "lettuce", "asparagus",
"potato", "wheat", "barley"]
farmers = ["Farmer Joe", "Upland Bros.", "Smith Gardening",
"Agrifun", "Organiculture", "BioGoods Ltd.", "Cornylee Corp."]
harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0],
[2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0],
[1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0],
[0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0],
[0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0],
[1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1],
[0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3]])
fig, ax = plt.subplots()
im = ax.imshow(harvest)
# Show all ticks and label them with the respective list entries
# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
rotation_mode="anchor")
# Loop over data dimensions and create text annotations.
for i in range(len(vegetables)):
for j in range(len(farmers)):
text = ax.text(j, i, harvest[i, j],
ha="center", va="center", color="w")
ax.set_xticks(np.arange(len(farmers)), labels=farmers)
ax.set_yticks(np.arange(len(vegetables)), labels=vegetables)
# Adding second y axis
par2 = ax.twinx() # probably wrong?
par2.set_ylim(ax.get_ylim())
par2.spines["left"].set_position(("axes", -0.3))
par2.tick_params('both', length=0, width=0, which='minor')
par2.tick_params('both', direction='in', which='major')
par2.yaxis.tick_left()
par2.yaxis.set_label_position("left")
par2.spines["left"].set_visible(True)
par2.yaxis.set_major_formatter(ticker.NullFormatter())
par2.set_yticks([-0.5, 3.5, 6.5])
par2.yaxis.set_minor_locator(ticker.FixedLocator([2.0, 5.0]))
par2.yaxis.set_minor_formatter(ticker.FixedFormatter(['tasty', 'not tasty']))
ax.set_title("Harvest of local farmers (in tons/year)")
fig.tight_layout()
plt.show()
Solution
You have to pass aspect='auto'
as an additional argument to the imshow()
function. As stated in the documentation,
'auto': The Axes is kept fixed and the aspect is adjusted so that the data fit in the Axes. In general, this will result in non-square pixels.
The only difference is that you won't have squared pixels.
Answered By - Luke B
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.