Skip to content

Commit c33835e

Browse files
Merge branch 'master' into nocolor
2 parents 868da9d + b4cb434 commit c33835e

File tree

12 files changed

+106
-14
lines changed

12 files changed

+106
-14
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
56
## [4.9.0] - unreleased
67

78
### Added
@@ -13,6 +14,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1314

1415
- trendline traces are now of type `scattergl` when `render_mode="webgl"` in Plotly Express ([#2614](https://github.com/plotly/plotly.py/pull/2614))
1516

17+
### Updated
18+
19+
- Added all cartesian-2d Plotly Express functions, plus `imshow` to Pandas backend with `kind` option
20+
- `plotly.express.imshow` now uses data frame index and columns names and values to populate axis parameters by default ([#2539](https://github.com/plotly/plotly.py/pull/2539))
21+
22+
1623

1724
## [4.8.2] - 2020-06-26
1825

@@ -21,6 +28,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2128
- Updated Plotly.js to version 1.54.5. See the [plotly.js CHANGELOG](https://github.com/plotly/plotly.js/blob/v1.54.5/CHANGELOG.md) for more information.
2229
- `add_traces()` now accepts bare `int`-like values for `rows`/`cols` as well as lists thereof ([#2546](https://github.com/plotly/plotly.py/pull/2546)), with thanks to [@MCBoarder289](https://github.com/MCBoarder289) for the contribution!
2330

31+
2432
### Fixed
2533

2634
- `row`/`col` now accept `int`-like values, not strictly `int` values ([#2451](https://github.com/plotly/plotly.py/pull/2451)), with thanks to [@MCBoarder289](https://github.com/MCBoarder289) for the contribution!

doc/python/dropdowns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fig.update_scenes(
147147
aspectmode="manual"
148148
)
149149

150-
# Add drowdowns
150+
# Add dropdowns
151151
button_layer_1_height = 1.08
152152
fig.update_layout(
153153
updatemenus=[

doc/python/heatmaps.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jupyter:
3636

3737
### Heatmap with `plotly.express` and `px.imshow`
3838

39-
[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.imshow`, each value of the input array is represented as a heatmap pixel.
39+
[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on a variety of types of data](/python/px-arguments/) and produces [easy-to-style figures](/python/styling-plotly-express/). With `px.imshow`, each value of the input array or data frame is represented as a heatmap pixel.
4040

4141
For more examples using `px.imshow`, see the [tutorial on displaying image data with plotly](/python/imshow).
4242

@@ -49,6 +49,14 @@ fig = px.imshow([[1, 20, 30],
4949
fig.show()
5050
```
5151

52+
```python
53+
import plotly.express as px
54+
55+
df = px.data.medals_wide(indexed=True)
56+
fig = px.imshow(df)
57+
fig.show()
58+
```
59+
5260
### Customizing the axes and labels on a heatmap
5361

5462
You can use the `x`, `y` and `labels` arguments to customize the display of a heatmap, and use `.update_xaxes()` to move the x axis tick labels to the top:
@@ -182,4 +190,4 @@ Arrays of rasterized values build by datashader can be visualized using
182190
plotly's heatmaps, as shown in the [plotly and datashader tutorial](/python/datashader/).
183191

184192
#### Reference
185-
See https://plotly.com/python/reference/#heatmap for more information and chart attribute options!
193+
See https://plotly.com/python/reference/#heatmap for more information and chart attribute options!

doc/python/hover-text-and-formatting.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ df_2007 = px.data.gapminder().query("year==2007")
228228
fig = px.scatter(df_2007, x="gdpPercap", y="lifeExp", log_x=True, color='continent'
229229
)
230230
print("plotly express hovertemplate:", fig.data[0].hovertemplate)
231-
fig.update_traces(hovertemplate='GDP: %{x} <br>Life Expectany: %{y}') #
231+
fig.update_traces(hovertemplate='GDP: %{x} <br>Life Expectancy: %{y}') #
232232
fig.update_traces(hovertemplate=None, selector={'name':'Europe'}) # revert to default hover
233233
print("user_defined hovertemplate:", fig.data[0].hovertemplate)
234234
fig.show()
@@ -404,4 +404,4 @@ fig.show()
404404

405405
#### Reference
406406

407-
See https://plotly.com/python/reference/ for more information and chart attribute options!
407+
See https://plotly.com/python/reference/ for more information and chart attribute options!

doc/python/legend.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,10 @@ fig.add_trace(go.Streamtube(
428428
))
429429
# Update all traces together
430430
fig.update_traces(showlegend=True, showscale=False)
431-
fig.update_layout(width=600, title_text='Exporation of a vector field using several traces')
431+
fig.update_layout(width=600, title_text='Exploration of a vector field using several traces')
432432
fig.show()
433433
```
434434

435435
#### Reference
436436

437-
See https://plotly.com/python/reference/#layout-legend for more information!
437+
See https://plotly.com/python/reference/#layout-legend for more information!

doc/python/pandas-backend.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ fig.show()
9898

9999
### Supported Methods
100100

101-
The Plotly backend supports the following `kind`s of Pandas plots: `scatter`, `line`, `area`, `bar`, `barh`, `hist` and `box`, via the call pattern `df.plot(kind='scatter')` or `df.plot.scatter()`. These delegate to the corresponding Plotly Express functions.
101+
The Plotly backend supports the following `kind`s of Pandas plots: `scatter`, `line`, `area`, `bar`, `barh`, `hist` and `box`, via the call pattern `df.plot(kind='scatter')` or `df.plot.scatter()`. These delegate to the corresponding Plotly Express functions. In addition, the following are valid options to the `kind` argument of `df.plot()`: `violin`, `strip`, `funnel`, `density_heatmap`, `density_contour` and `imshow`, even though the call pattern `df.plot.violin()` is not supported for these kinds of charts, per the Pandas API.
102102

103103
```python
104104
import pandas as pd
@@ -198,4 +198,4 @@ fig.show()
198198

199199
### What about Cufflinks?
200200

201-
There also exists an independent third-party wrapper library around Plotly called [Cufflinks](https://github.com/santosjorge/cufflinks), which provides similar functionality (with an API closer to that of Pandas' default `matplotlib` backend) by adding a `.iplot()` method to Pandas dataframes, as it was developed before Pandas supported configurable backends. Issues and questions regarding Cufflinks should be [raised in the Cufflinks repository](https://github.com/santosjorge/cufflinks/issues/new).
201+
There also exists an independent third-party wrapper library around Plotly called [Cufflinks](https://github.com/santosjorge/cufflinks), which provides similar functionality (with an API closer to that of Pandas' default `matplotlib` backend) by adding a `.iplot()` method to Pandas dataframes, as it was developed before Pandas supported configurable backends. Issues and questions regarding Cufflinks should be [raised in the Cufflinks repository](https://github.com/santosjorge/cufflinks/issues/new).

doc/python/px-arguments.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ There are three common conventions for storing column-oriented data, usually in
4949
* **wide-form data** has one row per value of one of the first variable, and one column per value of the second variable. This is suitable for storing and displaying 2-dimensional data.
5050
* **mixed-form data** is a hybrid of long-form and wide-form data, with one row per value of one variable, and some columns representing values of another, and some columns representing more variables. See the [wide-form documentation](/python/wide-form/) for examples of how to use Plotly Express to visualize this kind of data.
5151

52-
Every Plotly Express function other than `imshow` can operate on long-form data, and in addition, the following 2D-Cartesian functions can operate on wide-form and mixed-form data: `px.scatter`, `px.line`, `px.area`, `px.bar`, `px.histogram`, `px.violin`, `px.box`, `px.strip`, `px.funnel`, `px.density_heatmap` and `px.density_contour`.
52+
Every Plotly Express function can operate on long-form data (other than `px.imshow` which operates only on wide-form input), and in addition, the following 2D-Cartesian functions can operate on wide-form and mixed-form data: `px.scatter`, `px.line`, `px.area`, `px.bar`, `px.histogram`, `px.violin`, `px.box`, `px.strip`, `px.funnel`, `px.density_heatmap` and `px.density_contour`.
5353

5454
By way of example here is the same data, represented in long-form first, and then in wide-form:
5555

@@ -241,4 +241,4 @@ fig = px.bar(df, x='year', y=gdp, color='continent', labels={'y':'log gdp'},
241241
hover_data=['country'],
242242
title='Evolution of world GDP')
243243
fig.show()
244-
```
244+
```

doc/python/wide-form.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ There are three common conventions for storing column-oriented data, usually in
4848
* **wide-form data** has one row per value of one of the first variable, and one column per value of the second variable. This is suitable for storing and displaying 2-dimensional data.
4949
* **mixed-form data** is a hybrid of long-form and wide-form data, with one row per value of one variable, and some columns representing values of another, and some columns representing more variables.
5050

51-
Every Plotly Express function other than `imshow` can operate on long-form data, and in addition, the following 2D-Cartesian functions can operate on wide-form and mixed-form data: `px.scatter`, `px.line`, `px.area`, `px.bar`, `px.histogram`, `px.violin`, `px.box`, `px.strip`, `px.funnel`, `px.density_heatmap` and `px.density_contour`.
51+
Every Plotly Express function can operate on long-form data (other than `px.imshow` which operates only on wide-form input), and in addition, the following 2D-Cartesian functions can operate on wide-form and mixed-form data: `px.scatter`, `px.line`, `px.area`, `px.bar`, `px.histogram`, `px.violin`, `px.box`, `px.strip`, `px.funnel`, `px.density_heatmap` and `px.density_contour`.
5252

5353
By way of example here is the same data, represented in long-form first, and then in wide-form:
5454

packages/python/plotly/plotly/__init__.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,20 @@ def plot(data_frame, kind, **kwargs):
8080
To activate, set pandas.options.plotting.backend="plotly"
8181
See https://github.com/pandas-dev/pandas/blob/master/pandas/plotting/__init__.py
8282
"""
83-
from .express import scatter, line, area, bar, box, histogram
83+
from .express import (
84+
scatter,
85+
line,
86+
area,
87+
bar,
88+
box,
89+
histogram,
90+
violin,
91+
strip,
92+
funnel,
93+
density_contour,
94+
density_heatmap,
95+
imshow,
96+
)
8497

8598
if kind == "scatter":
8699
new_kwargs = {k: kwargs[k] for k in kwargs if k not in ["s", "c"]}
@@ -96,9 +109,27 @@ def plot(data_frame, kind, **kwargs):
96109
if kind == "box":
97110
new_kwargs = {k: kwargs[k] for k in kwargs if k not in ["by"]}
98111
return box(data_frame, **new_kwargs)
99-
if kind in "hist":
112+
if kind in ["hist", "histogram"]:
100113
new_kwargs = {k: kwargs[k] for k in kwargs if k not in ["by", "bins"]}
101114
return histogram(data_frame, **new_kwargs)
115+
if kind == "violin":
116+
return violin(data_frame, **kwargs)
117+
if kind == "strip":
118+
return strip(data_frame, **kwargs)
119+
if kind == "funnel":
120+
return funnel(data_frame, **kwargs)
121+
if kind == "density_contour":
122+
return density_contour(data_frame, **kwargs)
123+
if kind == "density_heatmap":
124+
return density_heatmap(data_frame, **kwargs)
125+
if kind == "imshow":
126+
return imshow(data_frame, **kwargs)
127+
if kind == "heatmap":
128+
raise ValueError(
129+
"kind='heatmap' not supported plotting.backend='plotly'. "
130+
"Please use kind='imshow' or kind='density_heatmap'."
131+
)
132+
102133
raise NotImplementedError(
103134
"kind='%s' not yet supported for plotting.backend='plotly'" % kind
104135
)

packages/python/plotly/plotly/express/_imshow.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,17 @@ def imshow(
196196
labels["color"] = xarray.plot.utils.label_from_attrs(img)
197197
labels["color"] = labels["color"].replace("\n", "<br>")
198198
else:
199+
if hasattr(img, "columns") and hasattr(img.columns, "__len__"):
200+
if x is None:
201+
x = img.columns
202+
if labels.get("x", None) is None and hasattr(img.columns, "name"):
203+
labels["x"] = img.columns.name or ""
204+
if hasattr(img, "index") and hasattr(img.index, "__len__"):
205+
if y is None:
206+
y = img.index
207+
if labels.get("y", None) is None and hasattr(img.index, "name"):
208+
labels["y"] = img.index.name or ""
209+
199210
if labels.get("x", None) is None:
200211
labels["x"] = ""
201212
if labels.get("y", None) is None:

packages/python/plotly/plotly/tests/test_core/test_px/test_imshow.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,25 @@ def test_imshow_labels_and_ranges():
150150

151151
with pytest.raises(ValueError):
152152
fig = px.imshow([[1, 2], [3, 4], [5, 6]], x=["a"])
153+
154+
155+
def test_imshow_dataframe():
156+
df = px.data.medals_wide(indexed=False)
157+
fig = px.imshow(df)
158+
assert fig.data[0].x[0] == df.columns[0]
159+
assert fig.data[0].x[0] == "nation"
160+
assert fig.layout.xaxis.title.text is None
161+
assert fig.data[0].y[0] == df.index[0]
162+
assert fig.data[0].y[0] == 0
163+
assert fig.layout.yaxis.title.text is None
164+
165+
df = px.data.medals_wide(indexed=True)
166+
fig = px.imshow(df)
167+
assert fig.data[0].x[0] == df.columns[0]
168+
assert fig.data[0].x[0] == "gold"
169+
assert fig.layout.xaxis.title.text == df.columns.name
170+
assert fig.layout.xaxis.title.text == "medal"
171+
assert fig.data[0].y[0] == df.index[0]
172+
assert fig.data[0].y[0] == "South Korea"
173+
assert fig.layout.yaxis.title.text == df.index.name
174+
assert fig.layout.yaxis.title.text == "nation"

packages/python/plotly/plotly/tests/test_core/test_px/test_pandas_backend.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@
2222
(lambda df: df.boxplot(), px.box),
2323
(lambda df: df.hist(), px.histogram),
2424
(lambda df: df["A"].hist(), lambda df: px.histogram(df["A"])),
25+
(lambda df: df.plot(kind="line"), px.line),
26+
(lambda df: df.plot(kind="area"), px.area),
27+
(lambda df: df.plot(kind="bar"), px.bar),
28+
(lambda df: df.plot(kind="box"), px.box),
29+
(lambda df: df.plot(kind="hist"), px.histogram),
30+
(lambda df: df.plot(kind="histogram"), px.histogram),
31+
(lambda df: df.plot(kind="violin"), px.violin),
32+
(lambda df: df.plot(kind="strip"), px.strip),
33+
(lambda df: df.plot(kind="funnel"), px.funnel),
34+
(lambda df: df.plot(kind="density_contour"), px.density_contour),
35+
(lambda df: df.plot(kind="density_heatmap"), px.density_heatmap),
36+
(lambda df: df.plot(kind="imshow"), px.imshow),
2537
],
2638
)
2739
def test_pandas_equiv(pandas_fn, px_fn):

0 commit comments

Comments
 (0)