简体   繁体   中英

How to use scientific notation in seaborn heatmap labels?

I'm trying to get a heatmap using seaborn in python. Unfortunately it is not using scientific notation even though the numbers are very large. I was wondering if there's any simple way to convert to scientific notation or any other reasonable format. Here's a piece of code that shows the problem:

import seaborn as sns 
import numpy as np
C_vals = np.logspace(3, 10, 8)
g_vals = np.logspace(-6, 2, 9)
score = np.random.rand(len(g_vals), len(C_vals))
sns.heatmap(score, xticklabels=C_vals, yticklabels=g_vals)

The resulting plot is the following

格式错误的热图

If you can bear to do w/o sns.heatmap , its perhaps more natural to do this with pcolormesh

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np

C_vals = np.logspace(3, 10, 8)
g_vals = np.logspace(-6, 2, 9)
score = np.random.rand(len(g_vals),len(C_vals))

fig, ax = plt.subplots()

ax.pcolormesh(C_vals, g_vals, score)
ax.set_yscale('log')
ax.set_xscale('log')
plt.show()

在此处输入图片说明

As pointed out below, pcolormesh doesn't centre the same way. Further, it actually drops a level. While I have a PR in to change that behaviour, here is a workaround. I admit at this point, its not much more elegant than messing w/ the heatmap output.

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np

C_vals = np.logspace(3, 10, 8)
g_vals = np.logspace(-6, 2, 9)
# make bracketing:
def midpointext(x):
    return np.hstack(( 1.5 * x[0] - 0.5 * x[1],
            x[:-1] + 0.5 * np.diff(x),
            1.5 * x[-1] - 0.5 * x[-2]))
newC = np.log10(C_vals)
newC = midpointext(newC)
newC = 10**newC
newg = np.log10(g_vals)
newg = midpointext(newg)
newg = 10**newg
score = np.random.rand(len(g_vals),len(C_vals))
fig, ax = plt.subplots()

ax.pcolormesh(newC, newg, score)
ax.set_yscale('log')
ax.set_xscale('log')
plt.show()

在此处输入图片说明

The heatmap allows to create its labels from the input to the xticklabels / yticklabels command. Those are then put along the axes, so there is no numeric format to change their appearance.

An option is to format the labels prior to supplying them to the heatmap. To this end a matplotlib ScalarFormatter can be (mis)used, which allows to automatically generate a MathText string from a float number. The following would be an example:

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns 
import numpy as np

C_vals = np.logspace(3, 10, 8)
g_vals = np.logspace(-6, 2, 9)
score = np.random.rand(len(g_vals),len(C_vals))

tick = ticker.ScalarFormatter(useOffset=False, useMathText=True)
tick.set_powerlimits((0,0))

tc = [u"${}$".format(tick.format_data(x)) for x in C_vals]
tg = [u"${}$".format(tick.format_data(x)) for x in g_vals]

sns.heatmap(score, xticklabels=tc, yticklabels=tg)

plt.show()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM