Skip to content

Linetype tuples don't work. #352

@TyberiusPrime

Description

@TyberiusPrime

The documentation says scale_linetype_manual, parameters, values:
"Tuples of the form (offset, (on, off, on, off, ....)) e.g. (0, (1, 1)), (1, (2, 2)), (2, (5, 3, 1, 3))"

But that does not work :(.

import pandas as pd
import plotnine as p9
import numpy as np
line_type_count = 3
df = pd.DataFrame(
    {
        "x": np.random.random(size=100),
        "y": np.random.random(size=100),
        "lt": ([str(x) for x in range(line_type_count)] * 200)[:100],
    }
)
import plotnine as p9

g = p9.ggplot(df)
g += p9.geom_line(p9.aes(x='x', y='y', ymax='y+1', linetype="lt", group='lt'))
g += p9.scale_linetype_manual(values=(
    (0, (1, 1)), 
    (1, (2, 2)), 
    (2, (5, 3, 1, 3))
))
g
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/ssd/upstream/dev/lib/python3.7/site-packages/IPython/core/formatters.py in __call__(self, obj)
    700                 type_pprinters=self.type_printers,
    701                 deferred_pprinters=self.deferred_printers)
--> 702             printer.pretty(obj)
    703             printer.flush()
    704             return stream.getvalue()

/ssd/upstream/dev/lib/python3.7/site-packages/IPython/lib/pretty.py in pretty(self, obj)
    397                         if cls is not object \
    398                                 and callable(cls.__dict__.get('__repr__')):
--> 399                             return _repr_pprint(obj, self, cycle)
    400 
    401             return _default_pprint(obj, self, cycle)

/ssd/upstream/dev/lib/python3.7/site-packages/IPython/lib/pretty.py in _repr_pprint(obj, p, cycle)
    687     """A pprint that just redirects to the normal repr function."""
    688     # Find newlines and replace them with p.break_()
--> 689     output = repr(obj)
    690     for idx,output_line in enumerate(output.splitlines()):
    691         if idx:

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/ggplot.py in __repr__(self)
     86         # in the jupyter notebook.
     87         if not self.figure:
---> 88             self.draw()
     89         plt.show()
     90         return '<ggplot: (%d)>' % self.__hash__()

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/ggplot.py in draw(self, return_ggplot)
    179         # new frames knowing that they are separate from the original.
    180         with pd.option_context('mode.chained_assignment', None):
--> 181             return self._draw(return_ggplot)
    182 
    183     def _draw(self, return_ggplot=False):

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/ggplot.py in _draw(self, return_ggplot)
    186         # assign a default theme
    187         self = deepcopy(self)
--> 188         self._build()
    189 
    190         # If no theme we use the default

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/ggplot.py in _build(self)
    321         if len(npscales):
    322             layers.train(npscales)
--> 323             layers.map(npscales)
    324 
    325         # Train coordinate system

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/layer.py in map(self, scales)
    107     def map(self, scales):
    108         for l in self:
--> 109             l.data = scales.map_df(l.data)
    110 
    111     def finish_statistics(self):

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/scales/scales.py in map_df(self, df)
    195         # Each scale maps the columns it understands
    196         for sc in self:
--> 197             df = sc.map_df(df)
    198         return df
    199 

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/scales/scale.py in map_df(self, df)
    285         aesthetics = set(self.aesthetics) & set(df.columns)
    286         for ae in aesthetics:
--> 287             df[ae] = self.map(df[ae])
    288 
    289         return df

/ssd/upstream/plotnine_dev/linestyle_errors/plotnine/scales/scale.py in map(self, x, limits)
    438 
    439         if self.na_translate:
--> 440             bool_idx = pd.isnull(x) | pd.isnull(pal_match)
    441             if bool_idx.any():
    442                 pal_match = [x if i else self.na_value

/ssd/upstream/dev/lib/python3.7/site-packages/pandas/core/ops/__init__.py in wrapper(self, other)
   1319         #   integer dtypes.  Otherwise these are boolean ops
   1320         filler = fill_int if is_self_int_dtype and is_other_int_dtype else fill_bool
-> 1321         res_values = na_op(self.values, ovalues)
   1322         unfilled = self._constructor(res_values, index=self.index, name=res_name)
   1323         filled = filler(unfilled)

/ssd/upstream/dev/lib/python3.7/site-packages/pandas/core/ops/__init__.py in na_op(x, y)
   1252     def na_op(x, y):
   1253         try:
-> 1254             result = op(x, y)
   1255         except TypeError:
   1256             assert not isinstance(y, (list, ABCSeries, ABCIndexClass))

ValueError: operands could not be broadcast together with shapes (100,) (100,2) ```


(Matplotlib is 3.1.2, and I can't find any test for scale_linetype_manual)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions