How to add images to charts as background images or logos.
Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Sign up for early access now.
Add a Background Image¶In this page we explain how to add static, non-interactive images as background, logo or annotation images to a figure. For exploring image data in interactive charts, see the tutorial on displaying image data.
A background image can be added to the layout of a figure with fig.add_layout_image
or by setting the images
parameter of go.Layout
. The source
attribute of a go.layout.Image
can be the URL of an image, or a PIL Image object (from PIL import Image; img = Image.open('filename.png')
).
In [1]:
import plotly.graph_objects as go # Create figure fig = go.Figure() # Add trace fig.add_trace( go.Scatter(x=[0, 0.5, 1, 2, 2.2], y=[1.23, 2.5, 0.42, 3, 1]) ) # Add images fig.add_layout_image( dict( source="https://images.plot.ly/language-icons/api-home/python-logo.png", xref="x", yref="y", x=0, y=3, sizex=2, sizey=2, sizing="stretch", opacity=0.5, layer="below") ) # Set templates fig.update_layout(template="plotly_white") fig.show()
In [2]:
import plotly.graph_objects as go fig = go.Figure() fig.add_trace( go.Bar( x=["-35.3", "-15.9", "-15.8", "-15.6", "-11.1", "-9.6", "-9.2", "-3.5", "-1.9", "-0.9", "1.0", "1.4", "1.7", "2.0", "2.8", "6.2", "8.1", "8.5", "8.5", "8.6", "11.4", "12.5", "13.3", "13.7", "14.4", "17.5", "17.7", "18.9", "25.1", "28.9", "41.4"], y=["Designers, musicians, artists, etc.", "Secretaries and administrative assistants", "Waiters and servers", "Archivists, curators, and librarians", "Sales and related", "Childcare workers, home car workers, etc.", "Food preparation occupations", "Janitors, maids, etc.", "Healthcare technicians, assistants. and aides", "Counselors, social and religious workers", "Physical, life and social scientists", "Construction", "Factory assembly workers", "Machinists, repairmen, etc.", "Media and communications workers", "Teachers", "Mechanics, repairmen, etc.", "Financial analysts and advisers", "Farming, fishing and forestry workers", "Truck drivers, heavy equipment operator, etc.", "Accountants and auditors", "Human resources, management analysts, etc.", "Managers", "Lawyers and judges", "Engineers, architects and surveyors", "Nurses", "Legal support workers", "Computer programmers and system admin.", "Police officers and firefighters", "Chief executives", "Doctors, dentists and surgeons"], marker=go.bar.Marker( color="rgb(253, 240, 54)", line=dict(color="rgb(0, 0, 0)", width=2) ), orientation="h", ) ) # Add image fig.add_layout_image( dict( source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png", xref="paper", yref="paper", x=1, y=1.05, sizex=0.2, sizey=0.2, xanchor="right", yanchor="bottom" ) ) # update layout properties fig.update_layout( autosize=False, height=800, width=700, bargap=0.15, bargroupgap=0.1, barmode="stack", hovermode="x", margin=dict(r=20, l=300, b=75, t=125), title=("Moving Up, Moving Down<br>" + "<i>Percentile change in income between childhood and adulthood</i>"), ) fig.show()Label Spectroscopy Data by Adding Multiple Images¶
In [3]:
import plotly.graph_objects as go import numpy as np np.random.seed(1) from scipy.signal import savgol_filter # Simulate spectroscopy data def simulated_absorption(mu, sigma, intensity): data = [np.random.normal(mu[i], sigma[i], intensity[i]) for i in range(len(mu))] hists = [np.histogram(d, 1000, range=(200, 500), density=True) for d in data] ys = [y for y, x in hists] s = savgol_filter(np.max(ys, axis=0), 41, 3) return hists[0][1], s mus = [[290, 240, 260], [330, 350]] sigmas = [[4, 6, 10], [5, 4]] intensities = [[100000, 300000, 700000], [40000, 20000]] simulated_absorptions = [simulated_absorption(m, s, i) for m, s, i in zip(mus, sigmas, intensities)] # Create figure fig = go.Figure() # Create traces from data names = ["Benzene", "Naphthalene"] for (x, y), n in zip(simulated_absorptions, names): fig.add_trace(go.Scatter(x=x, y=y, name=n)) # Add images fig.add_layout_image( dict( source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/benzene.png", x=0.75, y=0.65, )) fig.add_layout_image(dict( source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/naphthalene.png", x=0.9, y=0.3, ) ) fig.update_layout_images(dict( xref="paper", yref="paper", sizex=0.3, sizey=0.3, xanchor="right", yanchor="bottom" )) # Add annotations fig.update_layout( annotations=[ dict( x=93.0 / 300, y=0.07 / 0.1, xref="paper", yref="paper", showarrow=True, arrowhead=0, opacity=0.5, ax=250, ay=-40, ), dict( x=156.0 / 300, y=0.04 / 0.1, xref="paper", yref="paper", showarrow=True, arrowhead=0, opacity=0.5, ax=140, ay=-10, ) ] ) # Configure axes fig.update_xaxes(title_text="Wavelength") fig.update_yaxes(title_text="Absorption", hoverformat=".3f") # Configure other layout properties fig.update_layout( title_text="Absorption Frequencies of Benzene and Naphthalene", height=500, width=900, template="plotly_white" ) fig.show()
In [4]:
import plotly.graph_objects as go # Create figure fig = go.Figure() # Constants img_width = 1600 img_height = 900 scale_factor = 0.5 # Add invisible scatter trace. # This trace is added to help the autoresize logic work. fig.add_trace( go.Scatter( x=[0, img_width * scale_factor], y=[0, img_height * scale_factor], mode="markers", marker_opacity=0 ) ) # Configure axes fig.update_xaxes( visible=False, range=[0, img_width * scale_factor] ) fig.update_yaxes( visible=False, range=[0, img_height * scale_factor], # the scaleanchor attribute ensures that the aspect ratio stays constant scaleanchor="x" ) # Add image fig.add_layout_image( dict( x=0, sizex=img_width * scale_factor, y=img_height * scale_factor, sizey=img_height * scale_factor, xref="x", yref="y", opacity=1.0, layer="below", sizing="stretch", source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/bridge.jpg") ) # Configure other layout fig.update_layout( width=img_width * scale_factor, height=img_height * scale_factor, margin={"l": 0, "r": 0, "t": 0, "b": 0}, ) # Disable the autosize on double click because it adds unwanted margins around the image # More detail: https://plotly.com/python/configuration-options/ fig.show(config={'doubleClick': 'reset'})Annotating layout image with shapes¶
introduced in plotly 4.7
It can be useful to add shapes to a layout image, for highlighting an object, drawing bounding boxes as part of a machine learning training set, or identifying seeds for a segmentation algorithm.
In order to enable shape drawing, you need to
'drawline'
,'drawopenpath'
, 'drawclosedpath'
, 'drawcircle'
, or 'drawrect'
)The style of new shapes is specified by the newshape
layout attribute. Shapes can be selected and modified after they have been drawn. More details and examples are given in the tutorial on shapes.
Drawing or modifying a shape triggers a relayout
event, which can be captured by a callback inside a Dash application.
In [5]:
import plotly.graph_objects as go fig = go.Figure() # Add image img_width = 1600 img_height = 900 scale_factor = 0.5 fig.add_layout_image( x=0, sizex=img_width, y=0, sizey=img_height, xref="x", yref="y", opacity=1.0, layer="below", source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/bridge.jpg" ) fig.update_xaxes(showgrid=False, range=(0, img_width)) fig.update_yaxes(showgrid=False, scaleanchor='x', range=(img_height, 0)) # Line shape added programatically fig.add_shape( type='line', xref='x', yref='y', x0=650, x1=1080, y0=380, y1=180, line_color='cyan' ) # Set dragmode and newshape properties; add modebar buttons fig.update_layout( dragmode='drawrect', newshape=dict(line_color='cyan'), title_text='Drag to add annotations - use modebar to change drawing tool' ) fig.show(config={'modeBarButtonsToAdd':['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape' ]})Images Placed Relative to Axes¶
Using xref='x domain'
or yref='y domain'
, images can be placed relative to axes. As an example, the following shows how to put an image in the top corner of a subplot (try panning and zooming the resulting figure):
In [6]:
import plotly.express as px df = px.data.iris() fig = px.scatter(df, x="sepal_length", y="sepal_width", facet_col="species") # sources of images sources = [ "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Iris_setosa_var._setosa_%282595031014%29.jpg/360px-Iris_setosa_var._setosa_%282595031014%29.jpg", "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Iris_versicolor_quebec_1.jpg/320px-Iris_versicolor_quebec_1.jpg", "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Iris_virginica_2.jpg/480px-Iris_virginica_2.jpg", ] # add images for col, src in enumerate(sources): fig.add_layout_image( row=1, col=col + 1, source=src, xref="x domain", yref="y domain", x=1, y=1, xanchor="right", yanchor="top", sizex=0.2, sizey=0.2, ) fig.show()What About Dash?¶
Dash is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.
Learn about how to install Dash at https://dash.plot.ly/installation.
Everywhere in this page that you see fig.show()
, you can display the same figure in a Dash application by passing it to the figure
argument of the Graph
component from the built-in dash_core_components
package like this:
import plotly.graph_objects as go # or plotly.express as px fig = go.Figure() # or any Plotly Express function e.g. px.bar(...) # fig.add_trace( ... ) # fig.update_layout( ... ) from dash import Dash, dcc, html app = Dash() app.layout = html.Div([ dcc.Graph(figure=fig) ]) app.run(debug=True, use_reloader=False) # Turn off reloader if inside Jupyter
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4