Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [4.9.0] - unreleased

### Updated

- `plotly.express.imshow` now uses data frame index names and values to populate axis parameters by default ([#2539](https://github.com/plotly/plotly.py/pull/2539))

## [4.8.2] - unreleased

### Fixed
Expand Down
12 changes: 10 additions & 2 deletions doc/python/heatmaps.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jupyter:

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

[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.
[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.

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

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

```python
import plotly.express as px

df = px.data.medals_wide(indexed=True)
fig = px.imshow(df)
fig.show()
```

### Customizing the axes and labels on a heatmap

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:
Expand Down Expand Up @@ -182,4 +190,4 @@ Arrays of rasterized values build by datashader can be visualized using
plotly's heatmaps, as shown in the [plotly and datashader tutorial](/python/datashader/).

#### Reference
See https://plotly.com/python/reference/#heatmap for more information and chart attribute options!
See https://plotly.com/python/reference/#heatmap for more information and chart attribute options!
4 changes: 2 additions & 2 deletions doc/python/px-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ There are three common conventions for storing column-oriented data, usually in
* **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.
* **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.

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`.
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`.

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

Expand Down Expand Up @@ -241,4 +241,4 @@ fig = px.bar(df, x='year', y=gdp, color='continent', labels={'y':'log gdp'},
hover_data=['country'],
title='Evolution of world GDP')
fig.show()
```
```
4 changes: 2 additions & 2 deletions doc/python/wide-form.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ There are three common conventions for storing column-oriented data, usually in
* **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.
* **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.

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`.
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`.

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

Expand Down Expand Up @@ -302,4 +302,4 @@ fig.show()

fig = px.box(wide_df, orientation="h")
fig.show()
```
```
11 changes: 11 additions & 0 deletions packages/python/plotly/plotly/express/_imshow.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ def imshow(
labels["color"] = xarray.plot.utils.label_from_attrs(img)
labels["color"] = labels["color"].replace("\n", "<br>")
else:
if hasattr(img, "columns") and hasattr(img.columns, "__len__"):
if x is None:
x = img.columns
if labels.get("x", None) is None and hasattr(img.columns, "name"):
labels["x"] = img.columns.name or ""
if hasattr(img, "index") and hasattr(img.index, "__len__"):
if y is None:
y = img.index
if labels.get("y", None) is None and hasattr(img.index, "name"):
labels["y"] = img.index.name or ""

if labels.get("x", None) is None:
labels["x"] = ""
if labels.get("y", None) is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,25 @@ def test_imshow_labels_and_ranges():

with pytest.raises(ValueError):
fig = px.imshow([[1, 2], [3, 4], [5, 6]], x=["a"])


def test_imshow_dataframe():
df = px.data.medals_wide(indexed=False)
fig = px.imshow(df)
assert fig.data[0].x[0] == df.columns[0]
assert fig.data[0].x[0] == "nation"
assert fig.layout.xaxis.title.text is None
assert fig.data[0].y[0] == df.index[0]
assert fig.data[0].y[0] == 0
assert fig.layout.yaxis.title.text is None

df = px.data.medals_wide(indexed=True)
fig = px.imshow(df)
assert fig.data[0].x[0] == df.columns[0]
assert fig.data[0].x[0] == "gold"
assert fig.layout.xaxis.title.text == df.columns.name
assert fig.layout.xaxis.title.text == "medal"
assert fig.data[0].y[0] == df.index[0]
assert fig.data[0].y[0] == "South Korea"
assert fig.layout.yaxis.title.text == df.index.name
assert fig.layout.yaxis.title.text == "nation"