Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Remove frequency_bar #955

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions plugins/plotly-express/docs/bar.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ bar_plot_smoke = dx.bar(sorted_tips, x="Day", y="TotalBill", by="Smoker")
bar_plot_sex = dx.bar(sorted_tips, x="Day", y="TotalBill", by="Sex")
```

### Frequency of categories

Visualize the frequency of categories in a column by passing to either the `x` or `y` argument.

```python
import deephaven.plot.express as dx
tips = dx.data.tips()

# count the number of occurrences of each day with a vertical bar plot
bar_plot_vertical = dx.bar(tips, x="Day")

# count the number of occurrences of each day with a horizontal bar plot
bar_plot_horizontal = dx.bar(tips, y="Day")
```

## API Reference
```{eval-rst}
.. dhautofunction:: deephaven.plot.express.bar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from .plots import (
area,
bar,
frequency_bar,
timeline,
histogram,
box,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .scatter import scatter, scatter_3d, scatter_polar, scatter_ternary
from .line import line, line_3d, line_polar, line_ternary
from .area import area
from .bar import bar, frequency_bar, timeline
from .bar import bar, timeline
from .distribution import histogram, violin, strip, box
from .financial import candlestick, ohlc
from .hierarchial import treemap, icicle, sunburst, funnel, funnel_area
Expand Down
105 changes: 8 additions & 97 deletions plugins/plotly-express/src/deephaven/plot/express/plots/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def bar(
Args:
table: A table to pull data from.
x: A column or list of columns that contain x-axis values.
If only x is specified, the y-axis values are the count of each unique x value.
y: A column or list of columns that contain y-axis values.
If only y is specified, the x-axis values are the count of each unique y value.
by: A column or list of columns that contain values to plot the figure traces by.
All values or combination of values map to a unique design. The variable
by_vars specifies which design elements are used.
Expand Down Expand Up @@ -144,7 +146,12 @@ def bar(
"""
args = locals()

return process_args(args, {"bar", "supports_lists"}, px_func=px.bar)
groups = {"bar", "supports_lists"}

if not x or not y:
groups.add("preprocess_freq")

return process_args(args, groups, px_func=px.bar)


def _bar_polar(
Expand Down Expand Up @@ -299,99 +306,3 @@ def timeline(
args = locals()

return process_args(args, {"bar", "preprocess_time"}, px_func=px.timeline)


def frequency_bar(
table: Table | None = None,
x: str | list[str] | None = None,
y: str | list[str] | None = None,
by: str | list[str] | None = None,
by_vars: str | list[str] = "color",
labels: dict[str, str] | None = None,
color: str | list[str] | None = None,
pattern_shape: str | list[str] | None = None,
color_discrete_sequence: list[str] | None = None,
color_discrete_map: dict[str | tuple[str], str] | None = None,
pattern_shape_sequence: list[str] | None = None,
pattern_shape_map: dict[str | tuple[str], str] | None = None,
opacity: float | None = None,
barmode: str = "relative",
log_x: bool = False,
log_y: bool = False,
range_x: list[int] | None = None,
range_y: list[int] | None = None,
text_auto: bool | str = False,
title: str | None = None,
template: str | None = None,
unsafe_update_figure: Callable = default_callback,
) -> DeephavenFigure:
"""Returns a bar chart that contains the counts of the specified columns

Args:
table: A table to pull data from.
x: A column or list of columns that contain x-axis values.
Only one of x or y can be specified. If x is specified, the bars
are drawn vertically.
y: A column or list of columns that contain y-axis values.
Only one of x or y can be specified. If y is specified, the bars
are drawn horizontally.
by: A column or list of columns that contain values to plot the figure traces by.
All values or combination of values map to a unique design. The variable
by_vars specifies which design elements are used.
This is overriden if any specialized design variables such as color are specified
by_vars: A string or list of string that contain design elements to plot by.
Can contain color and pattern_shape.
If associated maps or sequences are specified, they are used to map by column values
to designs. Otherwise, default values are used.
color: A column or list of columns that contain color values.
The value is used for a plot by on color.
See color_discrete_map for additional behaviors.
pattern_shape: A column or list of columns that contain pattern shape values.
The value is used for a plot by on pattern shape.
See pattern_shape_map for additional behaviors.
labels: A dictionary of labels mapping columns to new labels.
color_discrete_sequence: A list of colors to sequentially apply to
the series. The colors loop, so if there are more series than colors,
colors will be reused.
color_discrete_map: If dict, the keys should be strings of the column values (or a tuple
of combinations of column values) which map to colors.
pattern_shape_sequence: A list of patterns to sequentially apply
to the series. The patterns loop, so if there are more series than
patterns, patterns will be reused.
pattern_shape_map: If dict, the keys should be strings of the column values (or a tuple
of combinations of column values) which map to patterns.
opacity: Opacity to apply to all markers. 0 is completely transparent
and 1 is completely opaque.
barmode: If 'relative', bars are stacked. If 'overlay', bars are drawn on top
of each other. If 'group', bars are drawn next to each other.
log_x: A boolean that specifies if the corresponding axis is a log
axis or not.
log_y: A boolean that specifies if the corresponding axis is a log
axis or not.
range_x: A list of two numbers that specify the range of the x-axis.
range_y: A list of two numbers that specify the range of the y-axis.
text_auto: If True, display the value at each bar.
If a string, specifies a plotly texttemplate.
title: The title of the chart
template: The template for the chart.
unsafe_update_figure: An update function that takes a plotly figure
as an argument and optionally returns a plotly figure. If a figure is
not returned, the plotly figure passed will be assumed to be the return
value. Used to add any custom changes to the underlying plotly figure.
Note that the existing data traces should not be removed. This may lead
to unexpected behavior if traces are modified in a way that break data
mappings.

Returns:
DeephavenFigure: A DeephavenFigure that contains the bar chart

"""

if x and y:
raise ValueError("Cannot specify both x and y")

args = locals()

return process_args(
args, {"bar", "preprocess_freq", "supports_lists"}, px_func=px.bar
)
217 changes: 217 additions & 0 deletions plugins/plotly-express/test/deephaven/plot/express/plots/test_bar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import unittest

from ..BaseTest import BaseTestCase


class BarTestCase(BaseTestCase):
def setUp(self) -> None:
from deephaven import new_table
from deephaven.column import int_col

self.source = new_table(
[
int_col("X", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("X2", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("Y", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("Y2", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("size", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("text", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("hover_name", [1, 2, 2, 3, 3, 3, 4, 4, 5]),
int_col("category", [1, 2, 1, 2, 1, 2, 1, 2, 1]),
]
)

def test_basic_bar_x(self):
import src.deephaven.plot.express as dx
from deephaven.constants import NULL_LONG, NULL_INT

chart = dx.bar(self.source, x="X").to_dict(self.exporter)
plotly, deephaven = chart["plotly"], chart["deephaven"]

# pop template as we currently do not modify it
plotly["layout"].pop("template")

expected_data = [
{
"alignmentgroup": "True",
"hovertemplate": "X=%{x}<br>count=%{y}<extra></extra>",
"legendgroup": "",
"marker": {"color": "#636efa", "pattern": {"shape": ""}},
"name": "",
"offsetgroup": "",
"orientation": "v",
"showlegend": False,
"textposition": "auto",
"type": "bar",
"x": [NULL_INT],
"xaxis": "x",
"y": [NULL_LONG],
"yaxis": "y",
}
]

self.assertEqual(plotly["data"], expected_data)

expected_layout = {
"barmode": "relative",
"legend": {"tracegroupgap": 0},
"margin": {"t": 60},
"xaxis": {
"anchor": "y",
"domain": [0.0, 1.0],
"side": "bottom",
"title": {"text": "X"},
},
"yaxis": {
"anchor": "x",
"domain": [0.0, 1.0],
"side": "left",
"title": {"text": "count"},
},
}

self.assertEqual(plotly["layout"], expected_layout)

expected_mappings = [
{
"data_columns": {
"X": ["/plotly/data/0/x"],
"count": ["/plotly/data/0/y"],
},
"table": 0,
}
]

self.assertEqual(deephaven["mappings"], expected_mappings)

self.assertEqual(deephaven["is_user_set_template"], False)
self.assertEqual(deephaven["is_user_set_color"], False)

def test_basic_bar_y(self):
import src.deephaven.plot.express as dx
from deephaven.constants import NULL_LONG, NULL_INT

chart = dx.bar(self.source, y="Y").to_dict(self.exporter)
plotly, deephaven = chart["plotly"], chart["deephaven"]

# pop template as we currently do not modify it
plotly["layout"].pop("template")

expected_data = [
{
"alignmentgroup": "True",
"hovertemplate": "count=%{x}<br>Y=%{y}<extra></extra>",
"legendgroup": "",
"marker": {"color": "#636efa", "pattern": {"shape": ""}},
"name": "",
"offsetgroup": "",
"orientation": "h",
"showlegend": False,
"textposition": "auto",
"type": "bar",
"x": [NULL_LONG],
"xaxis": "x",
"y": [NULL_INT],
"yaxis": "y",
}
]

self.assertEqual(plotly["data"], expected_data)

expected_layout = {
"barmode": "relative",
"legend": {"tracegroupgap": 0},
"margin": {"t": 60},
"xaxis": {
"anchor": "y",
"domain": [0.0, 1.0],
"side": "bottom",
"title": {"text": "count"},
},
"yaxis": {
"anchor": "x",
"domain": [0.0, 1.0],
"side": "left",
"title": {"text": "Y"},
},
}

self.assertEqual(plotly["layout"], expected_layout)

expected_mappings = [
{
"data_columns": {
"Y": ["/plotly/data/0/y"],
"count": ["/plotly/data/0/x"],
},
"table": 0,
}
]

self.assertEqual(deephaven["mappings"], expected_mappings)

self.assertEqual(deephaven["is_user_set_template"], False)
self.assertEqual(deephaven["is_user_set_color"], False)

def test_basic_bar_x_y(self):
import src.deephaven.plot.express as dx
from deephaven.constants import NULL_INT

chart = dx.bar(self.source, x="X", y="Y").to_dict(self.exporter)
plotly, deephaven = chart["plotly"], chart["deephaven"]

# pop template as we currently do not modify it
plotly["layout"].pop("template")

expected_data = [
{
"alignmentgroup": "True",
"hovertemplate": "X=%{x}<br>Y=%{y}<extra></extra>",
"legendgroup": "",
"marker": {"color": "#636efa", "pattern": {"shape": ""}},
"name": "",
"offsetgroup": "",
"orientation": "v",
"showlegend": False,
"textposition": "auto",
"type": "bar",
"x": [NULL_INT],
"xaxis": "x",
"y": [NULL_INT],
"yaxis": "y",
}
]

self.assertEqual(plotly["data"], expected_data)

expected_layout = {
"barmode": "relative",
"legend": {"tracegroupgap": 0},
"margin": {"t": 60},
"xaxis": {
"anchor": "y",
"domain": [0.0, 1.0],
"side": "bottom",
"title": {"text": "X"},
},
"yaxis": {
"anchor": "x",
"domain": [0.0, 1.0],
"side": "left",
"title": {"text": "Y"},
},
}

self.assertEqual(plotly["layout"], expected_layout)

expected_mappings = [
{
"data_columns": {"X": ["/plotly/data/0/x"], "Y": ["/plotly/data/0/y"]},
"table": 0,
}
]

self.assertEqual(deephaven["mappings"], expected_mappings)

self.assertEqual(deephaven["is_user_set_template"], False)
self.assertEqual(deephaven["is_user_set_color"], False)
Loading