e-hulten / july

A small library for creating pretty heatmaps of daily data.
MIT License
217 stars 27 forks source link

`value_label` - `add_value_label` - color of value_label #23

Open Witold1 opened 2 years ago

Witold1 commented 2 years ago

Describe the workflow you want to enable

Hi all, I wanted to use gray-scale colormap and add labels. july.calendar_plot and july.month_plot allowed me to add labels (a.k.a. ticks, values inside calendar cells) with value_label=True param, but did not allow me to change the color of these labels.

Example image and code attached

july.calendar_plot(data=df_plot.values, dates=df_plot.index, cmap="gray_r", value_label=True, title=False)

image

Describe your proposed solution

  1. As far as I understand the source code, the affected line is below: https://github.com/e-hulten/july/blob/master/src/july/helpers.py#L116
    july/src/july/helpers.py
    > 105 | def add_value_label(ax, cal, value_format):
    > ...
    > 118 | ax.text(j + 0.5, i + 0.5, val_format.format(z), ha="center", va="center")
  2. Objects of matplotlib.axes.Axes.text class have color or c - color parameter documentation link.
  3. We might add additional param responsible for color of values or transfer **kwargs

Describe alternatives you've considered, if relevant

Mayhap there are other ways to fix it

Additional context

Same issue may occur with other colormaps - it is difficult to separate dark colors from dark backgrounds (or to separate same tints, shades, tones in general). Also, color are important both from æsthetical and accessibility points see

Witold1 commented 2 years ago

Workaround solution Currently, to change the color (or other properties) of text of values one may use functionality of rather "advanced" matplotlib:

  1. Create the chart "as-is" with value_label=True
  2. Get these texts (matplotlib.text.Text objects) children artists (ax.get_children() function) from objects of matplotlib.axes._subplots.AxesSubplot class
    > `ax[indx].texts` or custom loop over `ax[indx].get_children()`
  3. Set desired color manually for these texts objects
    > `plt.setp(ax[indx].texts, color=color)` or custom loop with `Text.set_color(color)`

Sources (official documentation):

matplotlib.__version__ = 3.4.3