Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cf6f44a

Browse files
Merge branch 'fix-local-commands' of https://github.com/plotly/plotly.py into fix-local-commands
2 parents 15ccb6b + 2f6d1c7 commit cf6f44a

File tree

6 files changed

+162
-10
lines changed

6 files changed

+162
-10
lines changed

‎CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
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+
## Unreleased
6+
7+
### Updated
8+
- Updated Plotly.js from version 3.0.1 to version 3.0.3. See the [plotly.js CHANGELOG](https://github.com/plotly/plotly.js/blob/master/CHANGELOG.md#303----2025年07月23日) for more information.
9+
10+
### Added
11+
- Exposed `plotly.io.get_chrome()` as a function which can be called from within a Python script. [[#5282](https://github.com/plotly/plotly.py/pull/5282)]
12+
513
## [6.2.0] - 2025年06月26日
614

715
### Added

‎doc/python/figurewidget.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jupyter:
2222
pygments_lexer: ipython3
2323
version: 3.6.5
2424
plotly:
25-
description: Introduction to the new Plotly FigureWidget
25+
description: Introduction to the Plotly FigureWidget
2626
display_as: chart_events
2727
language: python
2828
layout: base
@@ -34,6 +34,12 @@ jupyter:
3434
redirect_from: /python/ipython-widgets/
3535
---
3636

37+
The Plotly FigureWidget allows you to add Plotly charts as interactive widgets in Jupyter and other compatible notebooks. To use the FigureWidget, you'll need to install `anywidget`:
38+
39+
```bash
40+
pip install anywidget
41+
```
42+
3743
#### Create a Simple FigureWidget
3844
Create an empty FigureWidget and then view it.
3945

‎doc/python/line-and-scatter.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,144 @@ fig.update_traces(textposition="bottom right")
284284
fig.show()
285285
```
286286

287+
### Swarm (or Beeswarm) Plots
288+
289+
Swarm plots show the distribution of values in a column by giving each entry one dot and adjusting the y-value so that dots do not overlap and appear symmetrically around the y=0 line. They complement [histograms](https://plotly.com/python/histograms/), [box plots](https://plotly.com/python/box-plots/), and [violin plots](https://plotly.com/python/violin/). This example could be generalized to implement a swarm plot for multiple categories by adjusting the y-coordinate for each category.
290+
291+
```python
292+
import pandas as pd
293+
import plotly.express as px
294+
import collections
295+
296+
297+
def negative_1_if_count_is_odd(count):
298+
# if this is an odd numbered entry in its bin, make its y coordinate negative
299+
# the y coordinate of the first entry is 0, so entries 3, 5, and 7 get
300+
# negative y coordinates
301+
if count % 2 == 1:
302+
return -1
303+
else:
304+
return 1
305+
306+
307+
def swarm(
308+
X_series,
309+
fig_title,
310+
point_size=16,
311+
fig_width=800,
312+
gap_multiplier=1.2,
313+
bin_fraction=0.95, # slightly undersizes the bins to avoid collisions
314+
):
315+
# sorting will align columns in attractive c-shaped arcs rather than having
316+
# columns that vary unpredictably in the x-dimension.
317+
# We also exploit the fact that sorting means we see bins sequentially when
318+
# we add collision prevention offsets.
319+
X_series = X_series.copy().sort_values()
320+
321+
# we need to reason in terms of the marker size that is measured in px
322+
# so we need to think about each x-coordinate as being a fraction of the way from the
323+
# minimum X value to the maximum X value
324+
min_x = min(X_series)
325+
max_x = max(X_series)
326+
327+
list_of_rows = []
328+
# we will count the number of points in each "bin" / vertical strip of the graph
329+
# to be able to assign a y-coordinate that avoids overlapping
330+
bin_counter = collections.Counter()
331+
332+
for x_val in X_series:
333+
# assign this x_value to bin number
334+
# each bin is a vertical strip slightly narrower than one marker
335+
bin = (((fig_width*bin_fraction*(x_val-min_x))/(max_x-min_x)) // point_size)
336+
337+
# update the count of dots in that strip
338+
bin_counter.update([bin])
339+
340+
# remember the "y-slot" which tells us the number of points in this bin and is sufficient to compute the y coordinate unless there's a collision with the point to its left
341+
list_of_rows.append(
342+
{"x": x_val, "y_slot": bin_counter[bin], "bin": bin})
343+
344+
# iterate through the points and "offset" any that are colliding with a
345+
# point to their left apply the offsets to all subsequent points in the same bin.
346+
# this arranges points in an attractive swarm c-curve where the points
347+
# toward the edges are (weakly) further right.
348+
bin = 0
349+
offset = 0
350+
for row in list_of_rows:
351+
if bin != row["bin"]:
352+
# we have moved to a new bin, so we need to reset the offset
353+
bin = row["bin"]
354+
offset = 0
355+
# see if we need to "look left" to avoid a possible collision
356+
for other_row in list_of_rows:
357+
if (other_row["bin"] == bin-1):
358+
# "bubble" the entry up until we find a slot that avoids a collision
359+
while ((other_row["y_slot"] == row["y_slot"]+offset)
360+
and (((fig_width*(row["x"]-other_row["x"]))/(max_x-min_x)
361+
// point_size) < 1)):
362+
offset += 1
363+
# update the bin count so we know whether the number of
364+
# *used* slots is even or odd
365+
bin_counter.update([bin])
366+
367+
row["y_slot"] += offset
368+
# The collision free y coordinate gives the items in a vertical bin
369+
# y-coordinates to evenly spread their locations above and below the
370+
# y-axis (we'll make a correction below to deal with even numbers of
371+
# entries). For now, we'll assign 0, 1, -1, 2, -2, 3, -3 ... and so on.
372+
# We scale this by the point_size*gap_multiplier to get a y coordinate
373+
# in px.
374+
row["y"] = (row["y_slot"]//2) * \
375+
negative_1_if_count_is_odd(row["y_slot"])*point_size*gap_multiplier
376+
377+
# if the number of points is even, move y-coordinates down to put an equal
378+
# number of entries above and below the axis
379+
for row in list_of_rows:
380+
if bin_counter[row["bin"]] % 2 == 0:
381+
row["y"] -= point_size*gap_multiplier/2
382+
383+
df = pd.DataFrame(list_of_rows)
384+
# One way to make this code more flexible to e.g. handle multiple categories
385+
# would be to return a list of "swarmified" y coordinates here and then plot
386+
# outside the function.
387+
# That generalization would let you "swarmify" y coordinates for each
388+
# category and add category specific offsets to put the each category in its
389+
# own row
390+
391+
fig = px.scatter(
392+
df,
393+
x="x",
394+
y="y",
395+
title=fig_title,
396+
)
397+
# we want to suppress the y coordinate in the hover value because the
398+
# y-coordinate is irrelevant/misleading
399+
fig.update_traces(
400+
marker_size=point_size,
401+
# suppress the y coordinate because the y-coordinate is irrelevant
402+
hovertemplate="<b>value</b>: %{x}",
403+
)
404+
# we have to set the width and height because we aim to avoid icon collisions
405+
# and we specify the icon size in the same units as the width and height
406+
fig.update_layout(width=fig_width, height=(
407+
point_size*max(bin_counter.values())+200))
408+
fig.update_yaxes(
409+
showticklabels=False, # Turn off y-axis labels
410+
ticks='', # Remove the ticks
411+
title=""
412+
)
413+
return fig
414+
415+
416+
df = px.data.iris() # iris is a pandas DataFrame
417+
fig = swarm(df["sepal_length"], "Sepal length distribution from 150 iris samples")
418+
# The iris data set entries are rounded so there are no collisions.
419+
# a more interesting test case for collision avoidance is:
420+
# fig = swarm(pd.Series([1, 1.5, 1.78, 1.79, 1.85, 2,
421+
# 2, 2, 2, 3, 3, 2.05, 2.1, 2.2, 2.5, 12]))
422+
fig.show()
423+
```
424+
287425
## Scatter and line plots with go.Scatter
288426

289427
If Plotly Express does not provide a good starting point, it is possible to use [the more generic `go.Scatter` class from `plotly.graph_objects`](/python/graph-objects/). Whereas `plotly.express` has two functions `scatter` and `line`, `go.Scatter` can be used both for plotting points (makers) or lines, depending on the value of `mode`. The different options of `go.Scatter` are documented in its [reference page](https://plotly.com/python/reference/scatter/).

‎doc/python/static-image-export.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,6 @@ Plotly also provides a CLI for installing Chrome from the command line.
6464

6565
Run `plotly_get_chrome` to install Chrome.
6666

67-
You can also install Chrome from within Python using `plotly.io.install_chrome()`
68-
69-
```python
70-
import plotly.io as pio
71-
72-
pio.install_chrome()
73-
```
7467

7568
See the **Additional Information on Browsers with Kaleido** section below for more details on browser compatibility for Kaleido.
7669

@@ -273,6 +266,8 @@ The following settings are available.
273266

274267
`mathjax`: Location of the MathJax bundle needed to render LaTeX characters. Defaults to a CDN location. If fully offline export is required, set this to a local MathJax bundle.
275268

269+
`plotlyjs`: Location of the Plotly.js bundle to use. Can be a local file path or URL. By default, Kaleido uses the Plotly.js bundle included with Plotly.py.
270+
276271
`topojson`: Location of the topojson files needed to render choropleth traces. Defaults to a CDN location. If fully offline export is required, set this to a local directory containing the Plotly.js topojson files.
277272

278273
`mapbox_access_token`: The default Mapbox access token (Kaleido v0 only). Mapbox traces are deprecated. See the [MapLibre Migration](https://plotly.com/python/mapbox-to-maplibre/) page for more details.

‎doc/python/text-and-annotations.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,11 @@ This example shows how to add a note about the data source or interpretation at
789789
```python
790790
import plotly.express as px
791791
df = px.data.iris()
792+
793+
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",
794+
size='petal_length', hover_data=['petal_width'])
795+
796+
792797
fig.update_layout(
793798
title=dict(text="Note: this is the Plotly title element.",
794799
# keeping this title string short avoids getting the text cut off in small windows

‎doc/python/tile-county-choropleth.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jupyter:
2222
pygments_lexer: ipython3
2323
version: 3.10.0
2424
plotly:
25-
description: How to make a choropleth map of US counties in Python with Plotly.
25+
description: How to make tile choropleth maps in Python with Plotly.
2626
display_as: maps
2727
language: python
2828
layout: base
@@ -254,4 +254,4 @@ fig.show()
254254

255255
See [function reference for `px.choropleth_map`](https://plotly.com/python-api-reference/generated/plotly.express.choropleth_map) or https://plotly.com/python/reference/choroplethmap/ for more information about the attributes available.
256256

257-
For Mapbox-based tile maps, see [function reference for `px.choropleth_mapbox`](https://plotly.com/python-api-reference/generated/plotly.express.choropleth_mapbox) or https://plotly.com/python/reference/choroplethmapbox/.
257+
For (deprecated) Mapbox-based tile maps, see [function reference for `px.choropleth_mapbox`](https://plotly.com/python-api-reference/generated/plotly.express.choropleth_mapbox) or https://plotly.com/python/reference/choroplethmapbox/.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /