Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9745c9b

Browse files
authored
Merge branch 'master' into conda-update
2 parents 5951882 + 477b88f commit 9745c9b

21 files changed

+118
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
3232
- Drop deprecated `autotick` attributes from cartesian axes [[#7236](https://github.com/plotly/plotly.js/pull/7236)]
3333
- Drop `transforms` from the API [[#7240](https://github.com/plotly/plotly.js/pull/7240), [#7254](https://github.com/plotly/plotly.js/pull/7254)]
3434

35-
## Fixed
35+
### Fixed
3636
- Fix a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused LaTeX to not render in plotly charts [[#4763](https://github.com/plotly/plotly.py/pull/4763)].
3737
- Fix `go.FigureWidget.show` to return `FigureWidget` instead of displaying `Figure` [[#4869](https://github.com/plotly/plotly.py/pull/4869)]
3838

packages/python/plotly/_plotly_utils/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ def to_typed_array_spec(v):
4343
"""
4444
v = copy_to_readonly_numpy_array(v)
4545

46+
# Skip b64 encoding if numpy is not installed,
47+
# or if v is not a numpy array, or if v is empty
4648
np = get_module("numpy", should_load=False)
47-
if not np or not isinstance(v, np.ndarray):
49+
if not np or not isinstance(v, np.ndarray) or v.size == 0:
4850
return v
4951

5052
dtype = str(v.dtype)

packages/python/plotly/plotly/express/_core.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,16 +1168,13 @@ def _escape_col_name(columns, col_name, extra):
11681168
return col_name
11691169

11701170

1171-
def to_unindexed_series(x, name=None, native_namespace=None):
1172-
"""Assuming x is list-like or even an existing Series, returns a new Series (with
1173-
its index reset if pandas-like). Stripping the index from existing pd.Series is
1174-
required to get things to match up right in the new DataFrame we're building.
1175-
"""
1171+
def to_named_series(x, name=None, native_namespace=None):
1172+
"""Assuming x is list-like or even an existing Series, returns a new Series named `name`."""
11761173
# With `pass_through=True`, the original object will be returned if unable to convert
11771174
# to a Narwhals Series.
11781175
x = nw.from_native(x, series_only=True, pass_through=True)
11791176
if isinstance(x, nw.Series):
1180-
return nw.maybe_reset_index(x).rename(name)
1177+
return x.rename(name)
11811178
elif native_namespace is not None:
11821179
return nw.new_series(name=name, values=x, native_namespace=native_namespace)
11831180
else:
@@ -1306,7 +1303,7 @@ def process_args_into_dataframe(
13061303
length,
13071304
)
13081305
)
1309-
df_output[col_name] = to_unindexed_series(
1306+
df_output[col_name] = to_named_series(
13101307
real_argument, col_name, native_namespace
13111308
)
13121309
elif not df_provided:
@@ -1343,7 +1340,7 @@ def process_args_into_dataframe(
13431340
)
13441341
else:
13451342
col_name = str(argument)
1346-
df_output[col_name] = to_unindexed_series(
1343+
df_output[col_name] = to_named_series(
13471344
df_input.get_column(argument), col_name
13481345
)
13491346
# ----------------- argument is likely a column / array / list.... -------
@@ -1362,7 +1359,7 @@ def process_args_into_dataframe(
13621359
argument.name is not None
13631360
and argument.name in df_input.columns
13641361
and (
1365-
to_unindexed_series(
1362+
to_named_series(
13661363
argument, argument.name, native_namespace
13671364
)
13681365
== df_input.get_column(argument.name)
@@ -1380,7 +1377,7 @@ def process_args_into_dataframe(
13801377
% (field, len_arg, str(list(df_output.keys())), length)
13811378
)
13821379

1383-
df_output[str(col_name)] = to_unindexed_series(
1380+
df_output[str(col_name)] = to_named_series(
13841381
x=argument,
13851382
name=str(col_name),
13861383
native_namespace=native_namespace,
@@ -2121,16 +2118,21 @@ def process_dataframe_timeline(args):
21212118
if args["x_start"] is None or args["x_end"] is None:
21222119
raise ValueError("Both x_start and x_end are required")
21232120

2124-
try:
2125-
df: nw.DataFrame = args["data_frame"]
2126-
df = df.with_columns(
2127-
nw.col(args["x_start"]).str.to_datetime().alias(args["x_start"]),
2128-
nw.col(args["x_end"]).str.to_datetime().alias(args["x_end"]),
2129-
)
2130-
except Exception:
2131-
raise TypeError(
2132-
"Both x_start and x_end must refer to data convertible to datetimes."
2133-
)
2121+
df: nw.DataFrame = args["data_frame"]
2122+
schema = df.schema
2123+
to_convert_to_datetime = [
2124+
col
2125+
for col in [args["x_start"], args["x_end"]]
2126+
if schema[col] != nw.Datetime and schema[col] != nw.Date
2127+
]
2128+
2129+
if to_convert_to_datetime:
2130+
try:
2131+
df = df.with_columns(nw.col(to_convert_to_datetime).str.to_datetime())
2132+
except Exception as exc:
2133+
raise TypeError(
2134+
"Both x_start and x_end must refer to data convertible to datetimes."
2135+
) from exc
21342136

21352137
# note that we are not adding any columns to the data frame here, so no risk of overwrite
21362138
args["data_frame"] = df.with_columns(

packages/python/plotly/plotly/tests/test_io/test_to_from_json.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import plotly.io as pio
33
import pytest
44
import plotly
5+
import numpy as np
56
import json
67
import os
78
import tempfile
@@ -259,3 +260,16 @@ def test_write_json_from_file_string(fig1, pretty, remove_uids):
259260
# Check contents that were written
260261
expected = pio.to_json(fig1, pretty=pretty, remove_uids=remove_uids)
261262
assert result == expected
263+
264+
265+
def test_to_dict_empty_np_array_int64():
266+
fig = go.Figure(
267+
[
268+
go.Bar(
269+
x=np.array([], dtype="str"),
270+
y=np.array([], dtype="int64"),
271+
)
272+
]
273+
)
274+
# to_dict() should not raise an exception
275+
fig.to_dict()

packages/python/plotly/plotly/tests/test_optional/test_px/test_px.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,18 @@ def test_render_mode(backend):
360360
)
361361
assert fig.data[0].type == "histogram2dcontour"
362362
assert fig.data[1].type == "scatter"
363+
364+
365+
def test_empty_df_int64(backend):
366+
# Load px data, then filter it such that the dataframe is empty
367+
df = px.data.tips(return_type=backend)
368+
df = nw.from_native(px.data.tips(return_type=backend))
369+
df_empty = df.filter(nw.col("day") == "banana").to_native()
370+
371+
fig = px.scatter(
372+
df_empty,
373+
x="total_bill",
374+
y="size", # size is an int64 column
375+
)
376+
# to_dict() should not raise an exception
377+
fig.to_dict()

packages/python/plotly/plotly/tests/test_optional/test_px/test_px_functions.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,29 @@ def test_timeline(constructor):
561561
msg = "Both x_start and x_end must refer to data convertible to datetimes."
562562
with pytest.raises(TypeError, match=msg):
563563
px.timeline(df, x_start="Start", x_end=["a", "b", "c"], y="Task", color="Task")
564+
565+
566+
@pytest.mark.parametrize(
567+
"datetime_columns",
568+
[
569+
["Start"],
570+
["Start", "Finish"],
571+
["Finish"],
572+
],
573+
)
574+
def test_timeline_cols_already_temporal(constructor, datetime_columns):
575+
# https://github.com/plotly/plotly.py/issues/4913
576+
data = {
577+
"Task": ["Job A", "Job B", "Job C"],
578+
"Start": ["2009-01-01", "2009-03-05", "2009-02-20"],
579+
"Finish": ["2009-02-28", "2009-04-15", "2009-05-30"],
580+
}
581+
df = (
582+
nw.from_native(constructor(data))
583+
.with_columns(nw.col(datetime_columns).str.to_datetime(format="%Y-%m-%d"))
584+
.to_native()
585+
)
586+
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="Task")
587+
assert len(fig.data) == 3
588+
assert fig.layout.xaxis.type == "date"
589+
assert fig.layout.xaxis.title.text is None

packages/python/plotly/plotly/tests/test_optional/test_px/test_px_input.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,29 @@ def test_splom_case(backend):
435435
assert np.all(fig.data[0].dimensions[0].values == ar[:, 0])
436436

437437

438+
def test_scatter_matrix_indexed_pandas():
439+
# https://github.com/plotly/plotly.py/issues/4917
440+
# https://github.com/plotly/plotly.py/issues/4788
441+
df = pd.DataFrame(
442+
{
443+
"x": [1, 2, 3, 4],
444+
"y": [10, 20, 10, 20],
445+
"z": [-1, -2, -3, -4],
446+
"color": [1, 2, 3, 4],
447+
}
448+
)
449+
df.index = pd.DatetimeIndex(
450+
[
451+
"1/1/2020 10:00:00+00:00",
452+
"2/1/2020 11:00:00+00:00",
453+
"3/1/2020 10:00:00+00:00",
454+
"4/1/2020 11:00:00+00:00",
455+
]
456+
)
457+
fig = px.scatter_matrix(df, color="color")
458+
assert np.all(fig.data[0].marker["color"] == np.array([1, 2, 3, 4]))
459+
460+
438461
def test_int_col_names(constructor):
439462
# DataFrame with int column names
440463
lengths = constructor({"0": np.random.random(100)})

packages/python/plotly/requires-install.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
###################################################
77

88
## dataframe agnostic layer ##
9-
narwhals>=1.13.3
9+
narwhals>=1.15.1
1010
packaging
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
requests==2.25.1
22
pytest==7.4.4
3-
narwhals>=1.13.3
3+
narwhals>=1.15.1

packages/python/plotly/test_requirements/requirements_310_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ kaleido
2020
orjson==3.8.12
2121
polars[timezone]
2222
pyarrow
23-
narwhals>=1.13.3
23+
narwhals>=1.15.1
2424
anywidget==0.9.13
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
requests==2.25.1
22
pytest==7.4.4
3-
narwhals>=1.13.3
3+
narwhals>=1.15.1

packages/python/plotly/test_requirements/requirements_311_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ kaleido
2020
orjson==3.8.12
2121
polars[timezone]
2222
pyarrow
23-
narwhals>=1.13.3
23+
narwhals>=1.15.1
2424
anywidget==0.9.13
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
requests==2.25.1
22
pytest==7.4.4
3-
narwhals>=1.13.3
3+
narwhals>=1.15.1

packages/python/plotly/test_requirements/requirements_312_no_numpy_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ kaleido
1919
orjson==3.9.10
2020
polars[timezone]
2121
pyarrow
22-
narwhals>=1.13.3
22+
narwhals>=1.15.1
2323
anywidget==0.9.13
2424
jupyter-console==6.4.4

packages/python/plotly/test_requirements/requirements_312_np2_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ kaleido
2121
orjson==3.9.10
2222
polars[timezone]
2323
pyarrow
24-
narwhals>=1.13.3
24+
narwhals>=1.15.1
2525
anywidget==0.9.13

packages/python/plotly/test_requirements/requirements_312_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ kaleido
2020
orjson==3.9.10
2121
polars[timezone]
2222
pyarrow
23-
narwhals>=1.13.3
23+
narwhals>=1.15.1
2424
anywidget==0.9.13
2525
jupyter-console==6.4.4
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
requests==2.25.1
22
pytest==8.1.1
3-
narwhals>=1.13.3
3+
narwhals>=1.15.1

packages/python/plotly/test_requirements/requirements_38_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ psutil==5.7.0
2020
kaleido
2121
polars[timezone]
2222
pyarrow
23-
narwhals>=1.13.3
23+
narwhals>=1.15.1
2424
anywidget==0.9.13
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
requests==2.25.1
22
pytest==6.2.3
3-
narwhals>=1.13.3
3+
narwhals>=1.15.1

packages/python/plotly/test_requirements/requirements_39_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ kaleido
2121
orjson==3.8.12
2222
polars[timezone]
2323
pyarrow
24-
narwhals>=1.13.3
24+
narwhals>=1.15.1
2525
anywidget==0.9.13

packages/python/plotly/test_requirements/requirements_39_pandas_2_optional.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ vaex
2121
pydantic<=1.10.11 # for vaex, see https://github.com/vaexio/vaex/issues/2384
2222
polars[timezone]
2323
pyarrow
24-
narwhals>=1.13.3
24+
narwhals>=1.15.1
2525
polars
2626
anywidget==0.9.13

0 commit comments

Comments
 (0)