How to use the parameter "annot_kws" of the function "sns.heatmap" to revise the annotaion text? - matplotlib

How can I draw such a heatmap using the "seaborn.heatmap" function?
The color shades are determined by matrix A and the annotation of each grid is determined by matrix B.
For example, if I get a matrix, I want its color to be displayed according to the z-score of this matrix, but the annotation remains the matrix itself.
I know I should resort to the parameter 'annot_kws', but how exactly should I write the code?

Instead of simply setting annot=True, annot= can be set to a dataframe (or 2D numpy array, or a list of lists) with the same number of rows and columns as the data. That way, the coloring will be applied using the data, and the annotation will come from annot. Seaborn will still take care to use white text for the dark cells and black text for the light ones.
annot_kws= is used to change the text properties, typically the fontsize. But you also could change the font itself, or the alignment if you'd used multiline text.
Here is an example using numbers 1 to 36 as annotation, but the numbers modulo 10 for the coloring. The annot_kws are used to enlarge and rotate the text. (Note that when the annotation are strings, you also need to set the format, e.g. fmt='').
import seaborn as sns
import numpy as np
a = pd.DataFrame({'count': [1, 2, 3]})
matrix_B = np.arange(1, 37).reshape(6, 6) # used for annotations
matrix_A = (matrix_B % 10) # used for coloring
sns.heatmap(data=matrix_A, annot=matrix_B,
annot_kws={'size': 20, 'rotation': 45},
square=True, cbar_kws={'label': 'last digit'})

Related

hvplot quadmesh custom dynamic cmap

I am trying to create a rangeSlider that controls the colorbar and bins of a hvplot quadmesh plot of gridded data. Right now I am using cmap and it is wonderful but I need a way to bin and color the data to a 3 color scheme namely,
(min, rangeSlider[0]) = Green labeled Good
(rangeSlider[0], rangeSlider[1]) = Yellow labeled Caution
(rangeSlider[1], max) = Red labeled Dangerous
So I made a couple of attempts but am not sure how to pass a ListedColormap from Matplotlib.colors as well as labels to a "bining" function of the quadmesh hvplot object.

How to create Correlation Heat Map of All Measure in Tableau?

I have Query with 10 Measures I am able to draw correlation heat map in Python using below?
import pandas as pd
import seaborn as sn
import matplotlib as mt
df = pd.read_sql('select statement')
sn.heatmap(df.corr(), annot=True)
mt.pyplot.show()
How can I make similar correlation heat map in Tableau?
The general way to make a heatmap in Tableau is to put a discrete field on rows and a discrete field on columns. Select the square mark type. Under Format, make a square cell size, and adjust the cell size to be as large as you prefer.
Then put a continuous field on the color shelf. Click on the color button to choose the color palette you like, and possibly turn on a border. Click on the size button to adjust the mark size to match the cell size.
There are a lot of good examples on Tableau Public.
https://public.tableau.com/app/search/vizzes/correlation%20matrix

Where is the list of available built-in colormap names?

Question
Where in the matplotlib documentations lists the name of available built-in colormap names to set as the name argument in matplotlib.cm.get_cmap(name)?
Choosing Colormaps in Matplotlib says:
Matplotlib has a number of built-in colormaps accessible via matplotlib.cm.get_cmap.
matplotlib.cm.get_cmap says:
matplotlib.cm.get_cmap(name=None, lut=None)
Get a colormap instance, defaulting to rc values if name is None.
name: matplotlib.colors.Colormap or str or None, default: None
https://www.kite.com/python/docs/matplotlib.pyplot.colormaps shows multiple names.
autumn sequential linearly-increasing shades of red-orange-yellow
bone sequential increasing black-white color map with a tinge of blue, to emulate X-ray film
cool linearly-decreasing shades of cyan-magenta
copper sequential increasing shades of black-copper
flag repetitive red-white-blue-black pattern (not cyclic at endpoints)
gray sequential linearly-increasing black-to-white grayscale
hot sequential black-red-yellow-white, to emulate blackbody radiation from an object at increasing temperatures
hsv cyclic red-yellow-green-cyan-blue-magenta-red, formed by changing the hue component in the HSV color space
inferno perceptually uniform shades of black-red-yellow
jet a spectral map with dark endpoints, blue-cyan-yellow-red; based on a fluid-jet simulation by NCSA [1]
magma perceptually uniform shades of black-red-white
pink sequential increasing pastel black-pink-white, meant for sepia tone colorization of photographs
plasma perceptually uniform shades of blue-red-yellow
prism repetitive red-yellow-green-blue-purple-...-green pattern (not cyclic at endpoints)
spring linearly-increasing shades of magenta-yellow
summer sequential linearly-increasing shades of green-yellow
viridis perceptually uniform shades of blue-green-yellow
winter linearly-increasing shades of blue-green
However, simply google 'matplotlib colormap names' seems not hitting the right documentation. I suppose there is a page listing the names as a enumeration or constant strings. Please help find it out.
There is some example code in the documentation (thanks to #Patrick Fitzgerald for posting the link in the comments, because it's not half as easy to find as it should be) which demonstrates how to generate a plot with an overview of the installed colormaps.
However, this uses an explicit list of maps, so it's limited to the specific version of matplotlib for which the documentation was written, as maps are added and removed between versions. To see what exactly your environment has, you can use this (somewhat crudely) adapted version of the code:
import numpy as np
import matplotlib.pyplot as plt
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
def plot_color_gradients(cmap_category, cmap_list):
# Create figure and adjust figure height to number of colormaps
nrows = len(cmap_list)
figh = 0.35 + 0.15 + (nrows + (nrows - 1) * 0.1) * 0.22
fig, axs = plt.subplots(nrows=nrows + 1, figsize=(6.4, figh))
fig.subplots_adjust(top=1 - 0.35 / figh, bottom=0.15 / figh,
left=0.2, right=0.99)
axs[0].set_title(cmap_category + ' colormaps', fontsize=14)
for ax, name in zip(axs, cmap_list):
ax.imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
ax.text(-0.01, 0.5, name, va='center', ha='right', fontsize=10,
transform=ax.transAxes)
# Turn off *all* ticks & spines, not just the ones with colormaps.
for ax in axs:
ax.set_axis_off()
cmaps = [name for name in plt.colormaps() if not name.endswith('_r')]
plot_color_gradients('all', cmaps)
plt.show()
This plots just all of them, without regarding the categories.
Since plt.colormaps() produces a list of all the map names, this version only removes all the names ending in '_r', (because those are the inverted versions of the other ones), and plots them all.
That's still a fairly long list, but you can have a look and then manually update/remove items from cmaps narrow it down to the ones you would consider for a given task.
You can also automatically reduce the list to monochrome/non-monochrome maps, because they provide that properties as an attribute:
cmaps_mono = [name for name in cmaps if plt.get_cmap(name).is_gray()]
cmaps_color = [name for name in cmaps if not plt.get_cmap(name).is_gray()]
That should at least give you a decent starting point.
It'd be nice if there was some way within matplotlib to select just certain types of maps (categorical, perceptually uniform, suitable for colourblind viewers ...), but I haven't found a way to do that automatically.
You can use my CMasher to make simple colormap overviews of a list of colormaps.
In your case, if you want to see what every colormap in MPL looks like, you can use the following:
import cmasher as cmr
import matplotlib.pyplot as plt
cmr.create_cmap_overview(plt.colormaps(), savefig='MPL_cmaps.png')
This will give you an overview with all colormaps that are registered in MPL, which will be all built-in colormaps and all colormaps my CMasher package adds, like shown below:

Option c and option s in pandas dataframe plot

I saw the following snippet of code from a book I am studying from
housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4,
s=housing["population"]/100, label="population", figsize=(10,7),
c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True,
)
plt.legend()
housing here is a pandas dataframe. I checked the documentation for pandas.DataFrame.plot on https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html. However, I don't see anywhere on the link where it states what c and s mean. I can infer from the resulting figure what it means, but I'm wondering why does the documentation not show this?
I believe you should look at matplotlib documentation site, mentioned here . Since the default plotting.backend is set to matplotlib in pandas, so these things are mentioned there. Here is what it say:
s: float or array-like, shape (n, ), optional
The marker size in points**2. Default is rcParams['lines.markersize'] ** 2.
c: array-like or list of colors or color, optional
The marker colors. Possible values:
A scalar or sequence of n numbers to be mapped to colors using cmap and norm.
A 2-D array in which the rows are RGB or RGBA.
A sequence of colors of length n.
A single color format string.

Saving an imshow-like image while preserving resolution

I have an (n, m) array that I've been visualizing with matplotlib.pyplot.imshow. I'd like to save this data in some type of raster graphics file (e.g. a png) so that:
The colors are the ones shown with imshow
Each element of the underlying array is exactly one pixel in the saved image -- meaning that if the underlying array is (n, m) elements, the image is NxM pixels. (I'm not interested in interpolation='nearest' in imshow.)
There is nothing in the saved image except for the pixels corresponding to the data in the array. (I.e. there's no white space around the edges, axes, etc.)
How can I do this?
I've seen some code that can kind of do this by using interpolation='nearest' and forcing matplotlib to (grudgingly) turn off axes, whitespace, etc. However, there must be some way to do this more directly -- maybe with PIL? After all, I have the underlying data. If I can get an RGB value for each element of the underlying array, then I can save it with PIL. Is there some way to extract the RGB data from imshow? I can write my own code to map the array values to RGB values, but I don't want to reinvent the wheel, since that functionality already exists in matplotlib.
As you already guessed there is no need to create a figure. You basically need three steps. Normalize your data, apply the colormap, save the image. matplotlib provides all the necessary functionality:
import numpy as np
import matplotlib.pyplot as plt
# some data (512x512)
import scipy.misc
data = scipy.misc.lena()
# a colormap and a normalization instance
cmap = plt.cm.jet
norm = plt.Normalize(vmin=data.min(), vmax=data.max())
# map the normalized data to colors
# image is now RGBA (512x512x4)
image = cmap(norm(data))
# save the image
plt.imsave('test.png', image)
While the code above explains the single steps, you can also let imsave do all three steps (similar to imshow):
plt.imsave('test.png', data, cmap=cmap)
Result (test.png):