holoviz / hvplot

A high-level plotting API for pandas, dask, xarray, and networkx built on HoloViews
https://hvplot.holoviz.org
BSD 3-Clause "New" or "Revised" License
1.14k stars 108 forks source link

Heatmap xticks customisation doesn't work #556

Open danmaty opened 3 years ago

danmaty commented 3 years ago

ALL software version info

hvplot==0.7.0 panel==0.10.3 Python 3.8

Description of expected behavior and the observed behavior

xticks (default=None): int or list Ticks along x specified as an integer, list of ticks positions, or list of tuples of the tick positions and labels

Tick positions work as the description says, but labels do not. This issue is present with all three options described above. If default it does work, in all other cases the plot will always display the tick position as labels. I've tried this in Jupyter Classic notebook and in PyCharm too. The symptoms are the same.

Complete, minimal, self-contained example code that reproduces the issue

The code below is from the examples page from the official website. I've just added the .opts part and using panel to display it.

import hvplot.pandas
from bokeh.sampledata.unemployment1948 import data
import panel as pn

data = data.set_index('Year').drop('Annual', axis=1).transpose()
x = data.hvplot.heatmap(
    x='columns',
    y='index',
    title='US Unemployment 1948—2016',
    cmap=["#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"],
    xaxis='top',
    rot=70,
    width=800, height=300).opts(
    toolbar=None,
    fontsize={'title': 10, 'xticks': 12, 'yticks': 5}
)
x.opts(xticks=[(10, 'foo'), (20, 'bar'), (30, 'lol')])
pn.panel(x).show()

Stack traceback and/or browser JavaScript console output

Screenshots or screencasts of the bug in action

issue

maximlt commented 2 years ago

I actually cannot reproduce this issue exactly as described as x.opts(xticks=[(10, 'foo'), (20, 'bar'), (30, 'lol')]) doesn't render anything at all.

Note that the values entered in the tuples are wrong, as the x-axis is composed of years (e.g. 1953).

This pure HoloViews code works:

import holoviews as hv
from bokeh.sampledata.unemployment1948 import data

hv.extension('bokeh')

data = data.set_index('Year').drop('Annual', axis=1).transpose()
cont = (data.columns, data.index, data.values)

hm = hv.HeatMap(cont)
hm.opts(xticks=[(1980, 'test')], clone=True)

However this doesn't work:

import holoviews as hv
from bokeh.sampledata.unemployment1948 import data

hv.extension('bokeh')

data = data.set_index('Year').drop('Annual', axis=1).transpose()
# The columns are converted to strings
cont = ([str(c) for c in data.columns], data.index, data.values)

hm = hv.HeatMap(cont)
# Raises a Python error
hm.opts(xticks=[('1980', 'test')], clone=True)
# Raises a JS error, same as hvPlot
hm.opts(xticks=[(1980, 'test')], clone=True)

It seems that internally hvPlot converts the columns index to an array that contains the string representation of the index values.

X-ref: https://github.com/holoviz/holoviews/issues/5493

maximlt commented 1 year ago

Other xticks issues in https://github.com/holoviz/hvplot/issues/320 and https://github.com/holoviz/hvplot/issues/975