Skip to content

Commit

Permalink
Merge pull request #2166 from plotly/imshow-xarray
Browse files Browse the repository at this point in the history
xarray support in imshow
  • Loading branch information
nicolaskruchten authored Mar 23, 2020
2 parents 0646966 + 21df030 commit 60e3666
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 54 deletions.
30 changes: 9 additions & 21 deletions doc/python/datashader.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ jupyter:
text_representation:
extension: .md
format_name: markdown
format_version: "1.2"
jupytext_version: 1.3.1
format_version: '1.2'
jupytext_version: 1.3.0
kernelspec:
display_name: Python 3
language: python
Expand All @@ -20,10 +20,9 @@ jupyter:
name: python
nbconvert_exporter: python
pygments_lexer: ipython3
version: 3.6.8
version: 3.7.3
plotly:
description:
How to use datashader to rasterize large datasets, and visualize
description: How to use datashader to rasterize large datasets, and visualize
the generated raster data with plotly.
display_as: scientific
language: python
Expand Down Expand Up @@ -98,30 +97,19 @@ fig.show()
```

```python
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd
import numpy as np
import datashader as ds
df = pd.read_parquet('https://raw.githubusercontent.com/plotly/datasets/master/2015_flights.parquet')

cvs = ds.Canvas(plot_width=100, plot_height=100)
agg = cvs.points(df, 'SCHEDULED_DEPARTURE', 'DEPARTURE_DELAY')
x = np.array(agg.coords['SCHEDULED_DEPARTURE'])
y = np.array(agg.coords['DEPARTURE_DELAY'])

# Assign nan to zero values so that the corresponding pixels are transparent
agg = np.array(agg.values, dtype=np.float)
agg[agg<1] = np.nan

fig = go.Figure(go.Heatmap(
z=np.log10(agg), x=x, y=y,
hoverongaps=False,
hovertemplate='Scheduled departure: %{x:.1f}h <br>Depature delay: %{y} <br>Log10(Count): %{z}',
colorbar=dict(title='Count (Log)', tickprefix='1.e')))
fig.update_xaxes(title_text='Scheduled departure')
fig.update_yaxes(title_text='Departure delay')
agg.values = np.log10(agg.values)
fig = px.imshow(agg, origin='lower', labels={'color':'Log10(count)'})
fig.update_traces(hoverongaps=False)
fig.update_layout(coloraxis_colorbar=dict(title='Count', tickprefix='1.e'))
fig.show()

```

```python
Expand Down
22 changes: 18 additions & 4 deletions doc/python/heatmaps.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +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. With `px.imshow`, each value of the input array is represented as a heatmap pixel.

`px.imshow` makes opiniated choices for representing heatmaps, such as using square pixels. To override this behaviour, you can use `fig.update_layout` or use the `go.Heatmap` trace from `plotly.graph_objects` as described below.
[Plotly Express](/python/plotly-express/) is the easy-to-use, high-level interface to Plotly, which [operates on "tidy" 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.

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

Expand All @@ -51,6 +49,22 @@ fig = px.imshow([[1, 20, 30],
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:

```python
import plotly.express as px
data=[[1, 25, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, 5, 20]]
fig = px.imshow(data,
labels=dict(x="Day of Week", y="Time of Day", color="Productivity"),
x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
y=['Morning', 'Afternoon', 'Evening']
)
fig.update_xaxes(side="top")
fig.show()
```

### Basic Heatmap with `plotly.graph_objects`

If Plotly Express does not provide a good starting point, it is also possible to use the more generic `go.Heatmap` function from `plotly.graph_objects`.
Expand All @@ -67,7 +81,7 @@ fig.show()

### Heatmap with Categorical Axis Labels

In this example we also show how to ignore [hovertext](https://plot.ly/python/hover-text-and-formatting/) when we have [missing values](https://plot.ly/python/missing_values) in the data by setting the [hoverongaps](https://plot.ly/python/reference/#heatmap-hoverongaps) to False.
In this example we also show how to ignore [hovertext](https://plot.ly/python/hover-text-and-formatting/) when we have [missing values](https://plot.ly/python/missing_values) in the data by setting the [hoverongaps](https://plot.ly/python/reference/#heatmap-hoverongaps) to False.

```python
import plotly.graph_objects as go
Expand Down
67 changes: 61 additions & 6 deletions doc/python/imshow.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.2'
jupytext_version: 1.3.0
jupytext_version: 1.3.1
kernelspec:
display_name: Python 3
language: python
Expand All @@ -20,7 +20,7 @@ jupyter:
name: python
nbconvert_exporter: python
pygments_lexer: ipython3
version: 3.7.3
version: 3.6.8
plotly:
description: How to display image data in Python with Plotly.
display_as: scientific
Expand Down Expand Up @@ -74,7 +74,7 @@ fig = px.imshow(img)
fig.show()
```

### Display single-channel 2D image as grayscale
### Display single-channel 2D data as a heatmap

For a 2D image, `px.imshow` uses a colorscale to map scalar data to colors. The default colorscale is the one of the active template (see [the tutorial on templates](/python/templates/)).

Expand All @@ -88,6 +88,17 @@ fig.show()

### Choose the colorscale to display a single-channel image

You can customize the [continuous color scale](/python/colorscales/) just like with any other Plotly Express function:

```python
import plotly.express as px
import numpy as np
img = np.arange(100).reshape((10, 10))
fig = px.imshow(img, color_continuous_scale='Viridis')
fig.show()
```

You can use this to make the image grayscale as well:

```python
import plotly.express as px
Expand All @@ -97,16 +108,60 @@ fig = px.imshow(img, color_continuous_scale='gray')
fig.show()
```

### Hiding the colorbar when displaying a single-channel image
### Hiding the colorbar and axis labels

See [the tutorial on coloraxis](/python/colorscales/#share-color-axis) for more details on coloraxis.
See the [continuous color](/python/colorscales/) and [cartesian axes](/python/axes/) pages for more details.

```python
import plotly.express as px
from skimage import data
img = data.camera()
fig = px.imshow(img, color_continuous_scale='gray')
fig.update_layout(coloraxis_showscale=False)
fig.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False)
fig.show()
```

### Customizing the axes and labels on a single-channel image

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:

```python
import plotly.express as px
data=[[1, 25, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, 5, 20]]
fig = px.imshow(data,
labels=dict(x="Day of Week", y="Time of Day", color="Productivity"),
x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
y=['Morning', 'Afternoon', 'Evening']
)
fig.update_xaxes(side="top")
fig.show()
```

### Display an xarray image with px.imshow

[xarrays](http://xarray.pydata.org/en/stable/) are labeled arrays (with labeled axes and coordinates). If you pass an xarray image to `px.imshow`, its axes labels and coordinates will be used for axis titles. If you don't want this behavior, you can pass `img.values` which is a NumPy array if `img` is an xarray. Alternatively, you can override axis titles hover labels and colorbar title using the `labels` attribute, as above.

```python
import plotly.express as px
import xarray as xr
# Load xarray from dataset included in the xarray tutorial
airtemps = xr.tutorial.open_dataset('air_temperature').air.sel(lon=250.0)
fig = px.imshow(airtemps.T, color_continuous_scale='RdBu_r', origin='lower')
fig.show()
```

### Display an xarray image with square pixels

For xarrays, by default `px.imshow` does not constrain pixels to be square, since axes often correspond to different physical quantities (e.g. time and space), contrary to a plain camera image where pixels are square (most of the time). If you want to impose square pixels, set the parameter `aspect` to "equal" as below.

```python
import plotly.express as px
import xarray as xr
airtemps = xr.tutorial.open_dataset('air_temperature').air.isel(time=500)
colorbar_title = airtemps.attrs['var_desc'] + '<br>(%s)'%airtemps.attrs['units']
fig = px.imshow(airtemps, color_continuous_scale='RdBu_r', aspect='equal')
fig.show()
```

Expand Down Expand Up @@ -201,7 +256,7 @@ fig.show()
### imshow and datashader

Arrays of rasterized values build by datashader can be visualized using
imshow. See the [plotly and datashader tutorial](/python/datashader/) for
imshow. See the [plotly and datashader tutorial](/python/datashader/) for
examples on how to use plotly and datashader.


Expand Down
13 changes: 3 additions & 10 deletions packages/python/plotly/plotly/express/_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@
except AttributeError: # python 2
getfullargspec = inspect.getargspec

# TODO contents of columns
# TODO explain categorical
# TODO handle color
# TODO handle details of box/violin/histogram
# TODO handle details of column selection with `dimensions`
# TODO document "or `None`, default `None`" in various places
# TODO standardize positioning and casing of 'default'

colref_type = "str or int or Series or array-like"
colref_desc = "Either a name of a column in `data_frame`, or a pandas Series or array_like object."
Expand Down Expand Up @@ -325,11 +318,11 @@
],
title=["str", "The figure title."],
template=[
"or dict or plotly.graph_objects.layout.Template instance",
"The figure template name or definition.",
"str or dict or plotly.graph_objects.layout.Template instance",
"The figure template name (must be a key in plotly.io.templates) or definition.",
],
width=["int (default `None`)", "The figure width in pixels."],
height=["int (default `600`)", "The figure height in pixels."],
height=["int (default `None`)", "The figure height in pixels."],
labels=[
"dict with str keys and str values (default `{}`)",
"By default, column names are used in the figure for axis titles, legend entries and hovers.",
Expand Down
Loading

0 comments on commit 60e3666

Please sign in to comment.