proplot-dev / proplot

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

Feature request: allow a single label for a group of lines #423

Open kinyatoride opened 1 year ago

kinyatoride commented 1 year ago

Description

Hi, is it possible to allow a single label for a group of lines? Currently, we need to pass the same number of labels for plotted elements. Here, I am showing an example of the wished behavior.

import numpy as np
import proplot as pplt

state = np.random.RandomState(51423)
x = np.linspace(0, 5, 20)
y1 = x[:, np.newaxis] + state.rand(20, 10)
y2 = x[::-1, np.newaxis] + state.rand(20, 10)

fig, ax = pplt.subplots()
ax.plot(y1, c='r', label='y1')
ax.plot(y2, c='b', label='y2')
ax.legend()

Expected behavior output

lukelbd commented 1 year ago

Makes sense. Maybe that should be the default behavior when label is used instead of labels (currently they are aliases)? For now here's a clumsy workaround:

import numpy as np
import proplot as pplt

state = np.random.RandomState(51423)
x = np.linspace(0, 5, 20)
y1 = x[:, np.newaxis] + state.rand(20, 10)
y2 = x[::-1, np.newaxis] + state.rand(20, 10)

fig, ax = pplt.subplots()
ax.plot(y1, c='r', label=['y1'] + 9 * [None])
ax.plot(y2, c='b', label=['y2'] + 9 * [None])
ax.legend()

iTerm2 UKZCDv tmp58qbkxgz

kinyatoride commented 1 year ago

On second thought, this might cause unexpected behavior. We need to specify a color (and other properties) for the group of lines. If we pass a single label without specifying a color, it won't know which color to use for the legend. We could use the property of the first line, but I don't know if this is a good idea.

lukelbd commented 1 year ago

Hmm yeah I can see that. And actually this is matplotlib's default behavior :/... not sure if any better than current proplot behavior of raising an error. Think I'll close then

import numpy as np
import matplotlib.pyplot as plt

state = np.random.RandomState(51423)
x = np.linspace(0, 5, 20)
y1 = x[:, np.newaxis] + state.rand(20, 10)
y2 = x[::-1, np.newaxis] + state.rand(20, 10)

fig, ax = plt.subplots()
ax.plot(y1, c='r', label='y1')
ax.plot(y2, c='b', label='y2')
ax.legend()

iTerm2 EYQgA4 tmpjutgkpek

lukelbd commented 1 year ago

On second thought... even though this matplotlib example is weird it probably makes more sense to assign identical labels to each line rather than raising an error. That way users can easily assign labels, but prevent repeated legend entries by (e.g.) manually passing a single line handle to legend(). I'll re-open