Reputation: 57
I have a heatmap with a few very high values (>5) that I would like to mask red. I have been able to generate my heatmap no problem, but I can't figure out how to mask the high values.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.pyplot as plt
from openpyxl import load_workbook
wb = load_workbook(filename='Lake Data.xlsx')
ws = wb['PC RFU']
data_rows = []
for row in ws['B77':'DL104']:
data_cols = []
for cell in row:
data_cols.append(cell.value)
data_rows.append(data_cols)
df = pd.DataFrame(data_rows)
print(df)
df.columns = df.iloc[0]
df = df.drop([0])
cols = df.select_dtypes(exclude=['float']).columns
df[cols] = df[cols].apply(pd.to_numeric, downcast='float', errors='coerce')
print(df)
print(df.columns)
print(df.info())
f, ax = plt.subplots(figsize=(18, 6))
f.suptitle('Site 03 PC/Chl', fontsize=16)
sns.heatmap(df.drop(['Depth (ft)'], axis='columns'), linewidths=0, ax=ax, cmap=color, robust='true', vmax=5) #,vmin=0,vmax=14, center=4
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
plt.xlabel('Date')
plt.ylabel('Depth (Ft.)')
plt.show()
The bright yellow squares on the right are actually between 5 and 15, and for those atypical high values >5 I'd like the squares to appear red. I can't seem to figure out how to use the mask feature to do this.
Bonus if someone can also tell me how to get rid of the "00:00:00" in the date axis!
Upvotes: 1
Views: 1653
Reputation: 80339
You can use a custom color map, and set its "over" color to red. That way, all values larger than vmax
will be colored red.
To restrict the x tick labels to their first 10 characters, you can use t.get_text()[:10]
.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(20, 100).cumsum(axis=0),
columns=pd.date_range('20210101', freq='D', periods=100))
fig, ax = plt.subplots(figsize=(18, 6))
fig.suptitle('Site 03 PC/Chl', fontsize=16)
my_cmap = plt.get_cmap('viridis').copy()
my_cmap.set_over('red')
sns.heatmap(df, linewidths=0, ax=ax, cmap=my_cmap, robust='true', vmax=5)
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)
ax.set_xticklabels([t.get_text()[:10] for t in ax.get_xticklabels()], rotation=90)
plt.xlabel('Date')
plt.ylabel('Depth (Ft.)')
plt.tight_layout()
plt.show()
Additionally, you might add extra parameters to the colorbar, e.g. sns.heatmap(..., cbar_kws={'pad': 0.02, 'extend': 'max', 'extendrect': True})
:
'pad': 0.02
to reduce the spacing between plot and colorbar'extend': 'max'
to show the "over" color in the colorbar'extendrect': True
to show the "over" color as a rectangle (default is a triangle)PS: You might try pd.read_excel()
to read the file directly and experiment with its parameters, in order to create the dataframe without manipulations.
Upvotes: 3