-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Colorbar with SymmetricalLogLocator : issue when handling only negative values #7202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The attached patch allows to draw ticks/ticklabels in case no decade (or only one) was selected based on vmin/vmax detected values.
|
might be linked to #7146 |
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
from matplotlib import ticker
X = -1 * np.random.randint(10, 90, size=(100, 100))
fig, ax = plt.subplots()
m = ax.imshow(X, norm=colors.SymLogNorm(1))
formatter = ticker.LogFormatter(10)
cb = fig.colorbar(m, format=formatter)
ax.set_title("label only base") |
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
from matplotlib import ticker
plt.ion()
X = np.random.randint(15, 90, size=(100, 100))
fig, ax = plt.subplots()
m = ax.imshow(X, norm=colors.LogNorm())
formatter = ticker.LogFormatter(10)
cb = fig.colorbar(m, format=formatter)
ax.set_title("label only base")
|
So… The behaviour is not the same for log and symlog Norm… minorticks appear with symlog but not log. |
@efiring @tacaswell @dopplershift Following monday's discussion, I've ran some tests. By default, Log formatter behave extremely poorly with colorbars. The current behaviour is as follows Disabling labelOnlyBase does not change anything: Disabling the sublabels only feature (introduced in august) does not change anything: To have a behaviour that seems reasonable for colorbars we need to modify both the sublabels filtering and the labelOnlyBase: Now going to using the LogFormatter on a log scaled plot while disabling the sublabels filtering does not change anything on this example: http://matplotlib.org/devdocs/examples/scales/scales.html From our discussion, I undersand that the labelOnlyBase=True is mostly use for minor ticks. I propose to change the default to have labelOnlyBase = False to remove or disable the sublabel filtering by default. I have yet to find a case where this new filtering improved the readibility of the figure, and I believe this may be due to improvements in the defaults of max number of ticks and placements of those ticks. I have to tweak matplotlib's code to add an option to disable the sublabels, that you can find in https://github.com/NelleV/matplotlib/tree/test_7202 But here are some tests scripts I wrote: 1. Colorbars import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker, colors
disable_sublabel = True
X_1 = np.random.randint(10000, 90000, size=(100, 100))
X_2 = np.random.randint(10000, 1000000, size=(100, 100))
formatter = ticker.LogFormatter(
10, disable_sublabel=disable_sublabel,
labelOnlyBase=False)
X = [X_1, X_2]
fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
for i, x in enumerate(X):
ax = axes[i]
m = ax.imshow(x, norm=colors.SymLogNorm(1))
ax.set_title("Disabling sublabels & labelOnlyBase")
cb = fig.colorbar(m, format=formatter, ax=ax, shrink=0.9, )
fig.savefig("images/log_colorbar_proposed_new_default.png")
formatter = ticker.LogFormatter(
10, disable_sublabel=disable_sublabel,
labelOnlyBase=True)
fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
for i, x in enumerate(X):
ax = axes[i]
m = ax.imshow(x, norm=colors.SymLogNorm(1))
ax.set_title("Disable sublabel only")
cb = fig.colorbar(m, format=formatter, ax=ax, shrink=0.9)
fig.savefig("images/log_colorbar_disable_sublabels_only.png")
formatter = ticker.LogFormatter(10, labelOnlyBase=False)
fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
for i, x in enumerate(X):
ax = axes[i]
m = ax.imshow(x, norm=colors.SymLogNorm(1))
ax.set_title("Log formatter labelOnlyBase=False")
cb = fig.colorbar(m, ax=ax, format=formatter, shrink=0.9)
fig.savefig("images/log_colorbar_disable_labelonlybase.png")
formatter = ticker.LogFormatter(10)
fig, axes = plt.subplots(ncols=2, figsize=(10, 4))
for i, x in enumerate(X):
ax = axes[i]
m = ax.imshow(x, norm=colors.SymLogNorm(1))
ax.set_title("Current Default")
cb = fig.colorbar(m, ax=ax, format=formatter, shrink=0.9)
fig.savefig("images/log_colorbar_default.png") 2. the scales example import numpy as np
from matplotlib import ticker
import matplotlib.pyplot as plt
disable_sublabel = True
old_formatter = ticker.LogFormatterSciNotation(
10, labelOnlyBase=False)
formatter = ticker.LogFormatterSciNotation(
10, disable_sublabel=True,
labelOnlyBase=False)
np.random.seed(19680801)
# make up some data in the interval ]0, 1[
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))
for i, fmt in enumerate([old_formatter, formatter]):
# plot with various axes scales
fig, axs = plt.subplots(2, 2)
# linear
ax = axs[0, 0]
ax.plot(x, y)
ax.set_yscale('linear')
ax.set_title('linear')
ax.grid(True)
# log
ax = axs[0, 1]
ax.plot(x, y)
ax.set_yscale('log')
ax.set_title('log')
ax.yaxis.set_major_formatter(fmt)
ax.grid(True)
# symmetric log
ax = axs[1, 1]
ax.plot(x, y - y.mean())
ax.set_yscale('symlog', linthreshy=0.05)
ax.set_title('symlog')
ax.yaxis.set_major_formatter(fmt)
ax.grid(True)
# logit
ax = axs[1, 0]
ax.plot(x, y)
ax.set_yscale('logit')
ax.set_title('logit')
#ax.yaxis.set_major_formatter(formatter)
ax.yaxis.set_minor_formatter(ticker.NullFormatter())
ax.grid(True)
plt.show()
if i == 0:
fig.savefig("images/example_old_formatter.png")
else:
fig.savefig("images/example_disabling_sublabels.png") 3. some random tests import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker, colors
formatter = ticker.LogFormatterSciNotation(
10, disable_sublabel=True,
labelOnlyBase=False)
X_1 = np.random.randint(10000, 90000, size=(1000,))
X_1.sort()
X_2 = np.random.randint(1e5, 1e12, size=(1000,))
X_2.sort()
X_3 = np.random.randint(1e5, 1e16, size=(1000,))
X_3.sort()
X = [X_1, X_2, X_3]
fig, ax = plt.subplots(ncols=len(X), nrows=2, figsize=(12, 6))
for i, x in enumerate(X):
ax[0, i].plot(x)
ax[0, i].set_yscale("symlog")
ax[1, i].plot(x)
ax[1, i].set_yscale("symlog")
ax[1, i].yaxis.set_major_formatter(formatter)
ax[0, 1].set_title("Symmetrical log")
fig, ax = plt.subplots(ncols=len(X), nrows=2, figsize=(12, 6))
for i, x in enumerate(X):
ax[0, i].plot(x)
ax[0, i].set_yscale("log")
ax[1, i].plot(x)
ax[1, i].set_yscale("log")
ax[1, i].yaxis.set_major_formatter(formatter)
ax[0, 1].set_title("Log")
l_f = ax[0, 1].yaxis.get_major_formatter()
|
Note that by default, labelOnlyBase is |
Tested with matplotlib 1.4.3 and 1.5.3 built from sources - python 2.7.11 - Windows and Linux (64-bit)
To reproduce this issue, choose a set of values X so that -100<X<-10, then plot a NonUniformImage and attach a colorbar with a SymmetricalLogLocator : no tick or ticklabel will be displayed on the colorbar.
The text was updated successfully, but these errors were encountered: