proplot-dev / proplot

🎨 A succinct matplotlib wrapper for making beautiful, publication-quality graphics
https://proplot.readthedocs.io
MIT License
1.07k stars 96 forks source link

Proplot ignores non-none vmin and vmax values on normalizer instances #400

Open Jhsmit opened 1 year ago

Jhsmit commented 1 year ago

Description

I'm trying to clip colors in a scatter plot using norm, but the keyword argument seems to be ignored, unless I pass a DiscreteNorm

Steps to reproduce

import proplot as pplt
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
import numpy as np

print(pplt.__version__)
import matplotlib
print(matplotlib.__version__)

x = np.arange(10)
y = np.random.rand(10)
c = x**2

fig, ax = pplt.subplots()
ax.scatter(x, y, c=c, cmap='viridis', norm=pplt.Norm('linear', 0., 1.))
ax.format(title='proplot')
pplt.show()

fig, ax = pplt.subplots()
ax.scatter(x, y, c=c, cmap='viridis', norm=pplt.DiscreteNorm(np.linspace(0, 1, 6)))
ax.format(title='proplot discrete')
pplt.show()

fig, ax = plt.subplots()
ax.scatter(x, y, c=c, cmap='viridis', norm=Normalize(0, 1))
ax.set_title("matplotlib")
pplt.show()

Proplot: image

Proplot with discrete norm: image

Matplotlib: image

Proplot version

matplotlib: 3.4.3 proplot: 0.9.5

lukelbd commented 1 year ago

Thanks for the report. For now, you can also accomplish clipping by passing vmin=0 and vmax=1 instead of a normalizer (this is not possible in matplotlib, but proplot tries to standardize arguments across different commands, so e.g. any command that accepts cmap also accepts colormap-related keywords like vmin, vmax, levels, etc.):

import proplot as pplt
import numpy as np

x = np.arange(10)
y = np.random.rand(10)
c = x**2

fig, ax = pplt.subplots()
ax.scatter(x, y, c=c, cmap='viridis', vmin=0, vmax=1)
ax.format(title='proplot')

iTerm2 6R1R0b tmpk_fte3v8

I see that in matplotlib, if a normalizer is passed with explicitly-set vmin and vmax values (i.e., not the default None values), then matplotlib will not set them automatically. However, proplot always overrides the vmin and vmax values. I'll change this so that normalizer vmin and vmax are respected.

Jhsmit commented 11 months ago

FYI the behavior is the same for pcolor / pcolormesh, also the passed normalizer is modified:


arr = np.random.rand(20, 40)*1000
xe = np.linspace(0, 1, num=40, endpoint=True)
ye = np.linspace(0, 1, num=20, endpoint=True)

fig, ax = pplt.subplots()
norm = pplt.Norm("linear", vmin=0, vmax=1)
print(norm.vmin, norm.vmax)
ax.pcolor(xe, ye, arr, cmap="viridis", norm=norm)
print(norm.vmin, norm.vmax)

prints 0.0 1.0 0.0 1000.0