How to edit plotly legends so that "color" and "symbol" will be combined to one?
import pandas as pd
import plotly.express as px
import numpy as np
from sklearn.decomposition import PCA
pca = PCA()
X_pca = pca.fit_transform(X)
fig = px.scatter(X_pca, x=0, y=1, color=df["subtype"], width=600, height=600, color_discrete_sequence=["red", "orange", "brown", "green"], title="Kernel PCA - tumor subtype vs normal", symbol=df["subtype"], symbol_sequence=['circle', 'circle', 'circle', 'square'])
fig.update_traces(marker=dict(size=5, line=dict(width=0.5, color='DarkSlateGrey')), selector=dict(mode='markers'))
fig.update_xaxes(automargin=True)
fig.update_yaxes(automargin=True)
fig.update_layout({'plot_bgcolor': 'rgb(240,240,240)', 'paper_bgcolor': 'rgb(240,240,240)',})
fig.show()
fig.write_image("meth_subtype_pca.png")
Current output :
The legend has "color, symbol"..."kirp, kirp" etc. I want to replace this with "subtype"..."KIRP".
This event is new to me; it is caused by specifying symbols using a PCA scatterplot. I confirmed the same event by adding symbols in the example in the reference. There doesn't seem to be a way to control this so I customize the graph created, one is taking the duplicate legend names and set() them to a single value. Also, the legend title is specified manually.
import pandas as pd
import plotly.express as px
import numpy as np
from sklearn.decomposition import PCA
df = px.data.iris()
X = df[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']]
pca = PCA()
X_pca = pca.fit_transform(X)
fig = px.scatter(X_pca,
x=0,
y=1,
color=df["species"],
width=600,
height=600,
color_discrete_sequence=["red", "orange", "brown", "green"],
title="Kernel PCA - tumor subtype vs normal",
symbol=df["species"],
symbol_sequence=['circle', 'circle', 'square']
)
fig.update_traces(marker=dict(size=5, line=dict(width=0.5, color='DarkSlateGrey')), selector=dict(mode='markers'))
fig.update_xaxes(automargin=True)
fig.update_yaxes(automargin=True)
fig.update_layout({'plot_bgcolor': 'rgb(240,240,240)', 'paper_bgcolor': 'rgb(240,240,240)',})
# update
for data in fig.data:
data['name'] = list(set(data['name'].split(', ')))[0]
fig.layout['legend']['title']['text'] = 'color'
fig.show()
#fig.write_image("meth_subtype_pca.png")
Related
I made a bar chart with python plotly, and I want to put a marker on a particular bar, example non-smoking females.
Does anyone know how to specify this?
I took an example from the plotly documentation, if I try to put the marker it just takes the center of the main category.
import plotly.express as px
df = px.data.tips()
fig = px.histogram(df, x="sex", y="total_bill",
color='smoker', barmode='group',
height=400)
#trying to set the marker
fig.add_trace(
go.Scatter(x=["Female"],
y=[1100]
))
fig.show()
inspired by this: https://community.plotly.com/t/grouped-bar-charts-with-corresponding-line-chart/19562/4
use xaxis2, work out position, have hardcoded it, but 0.15 has relationship to number of traces in bargoup and x value
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
df = px.data.tips()
fig = px.histogram(
df, x="sex", y="total_bill", color="smoker", barmode="group", height=400
)
# trying to set the marker
fig.add_trace(
go.Scatter(
x=[0.15],
y=[1100],
customdata=[["No", "Female"]],
xaxis="x2",
hovertemplate="smoker=%{customdata[0]}<br>sex=%{customdata[1]}<br>sum of total_bill=%{y}<extra></extra>",
)
)
fig.update_layout(xaxis2={"overlaying": "x", "range": [0, 1], "showticklabels": False})
fig
I am trying to use custom hexa codes for each bar in a plotly chart but I am not able to work this out.
Could someone please help me.
Below is the code I a working with
#Defining Custom Colors
colours = {'Base_Models': '#0C3B5D',
'Standard_scaled_scores': '#3EC1CD',
'Min_Max_scaled_scores': '#EF3A4C',
'Scaling & feature selection_scores': '#FCB94D'}
import plotly.express as px
fig = px.bar(compareModels_aft_Cleansing, x="Base_Models", y=["Base_Models_Scores",
"Standard_scaled_scores", "Min_Max_scaled_scores",
"Scaling & feature selection_scores"],
title="Training Scores", barmode='group', text = 'value',
hover_name="Base_Models",
hover_data={'Base_Models':False}, # remove species from hover data
color = colours)
you have not provided sample data so I have synthesized
your colours map as I understand your dataframe is incorrect. You are plotting Base_Models_Scores as a bar not Base_Models, this is the x-axis
the parameter you require is color_discrete_map to achieve your requirement
import pandas as pd
import numpy as np
# Defining Custom Colors
colours = {
"Base_Models_Scores": "#0C3B5D",
"Standard_scaled_scores": "#3EC1CD",
"Min_Max_scaled_scores": "#EF3A4C",
"Scaling & feature selection_scores": "#FCB94D",
}
# generate sample data...
compareModels_aft_Cleansing = pd.DataFrame(
{
**{"Base_Models": colours.keys()},
**{
c: np.random.randint(1, 4, len(colours.keys()))
for c in colours.keys()
},
}
)
import plotly.express as px
fig = px.bar(
compareModels_aft_Cleansing,
x="Base_Models",
y=[
"Base_Models_Scores",
"Standard_scaled_scores",
"Min_Max_scaled_scores",
"Scaling & feature selection_scores",
],
title="Training Scores",
barmode="group",
text="value",
hover_name="Base_Models",
hover_data={"Base_Models": False}, # remove species from hover data
color_discrete_map=colours,
)
fig
For research data visualisation I'd like to make an animated 3D surface plot in Plotly. The goal is to see the evolution of temperature in a box in function of time. But I don't know how to animate it.
At this moment I only have my plot at a give time.
This is my code:
import plotly
import plotly.graph_objects as go
#import plotly.express as px
import pandas as pd
#import numpy as np
#read CSV
z_data = pd.read_csv('data1.csv')# Read data from a csv
fig = go.Figure(data=[go.Surface(z=z_data.values)])
#projection 2D
fig.update_traces(contours_z=dict(show=True, usecolormap=True,
highlightcolor="tomato", project_z=True),
colorscale='portland')
#fig
fig.update_layout(title='data HEATPILES', autosize=False, width=650, height=500, margin=dict(l=0, r=0, b=0, t=0))
#show
plotly.offline.plot(fig)
data1.csv is only this:
data1.csv
But I have more data of the point's position in function of time and I would want to make an animated plot, so we could clearly see the evolution on time.
Here is the result at a given time
Plot at a given time
I've seen on the plotly documentation that it's possible to make animation with px.scatter and px.line from here, and from there that we can do it with image, so I guess it would be possible with surface plot.
Here is some example of the animation: https://plotly.com/python/#animations
Here is some example of the 3D surface plot: https://plotly.com/python/3d-surface-plots
If you could help me do you I would much appreciate !
Thank you for your help,
Theophile
Here is the full code for you:
import pandas as pd
import plotly.graph_objects as go
z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv').values
print(z_data)
z_data2 = z_data * 1.1
z_data3 = z_data * 1.2
z_data4 = z_data * 0.5
z_data_list = []
z_data_list.append(z_data)
z_data_list.append(z_data2)
z_data_list.append(z_data3)
z_data_list.append(z_data4)
z_data_list.append(z_data)
z_data_list.append(z_data2)
z_data_list.append(z_data3)
z_data_list.append(z_data4)
fig = go.Figure(
data=[go.Surface(z=z_data_list[0])],
layout=go.Layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None])])]),
frames=[go.Frame(data=[go.Surface(z=k)], name=str(i)) for i, k in enumerate(z_data_list)]
)
fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="tomato", project_z=True), colorscale='portland')
fig.update_layout(title='data HEATPILES', autosize=False, width=650, height=500, margin=dict(l=0, r=0, b=0, t=0))
def frame_args(duration):
return {
"frame": {"duration": duration},
"mode": "immediate",
"fromcurrent": True,
"transition": {"duration": duration, "easing": "linear"},
}
sliders = [
{
"pad": {"b": 10, "t": 60},
"len": 0.9,
"x": 0.1,
"y": 0,
"steps": [
{
"args": [[f.name], frame_args(0)],
"label": str(k),
"method": "animate",
}
for k, f in enumerate(fig.frames)
],
}
]
fig.update_layout(sliders=sliders)
import plotly.io as pio
ii = 1
pio.write_html(fig, file="Live3D_"+str(ii)+".html", auto_open=True)
# plotly.offline.plot(fig)
After a good research I built this code to plot a proper smooth 3D surface plot. Simply put the data_frame into this function. You'll get a proper smoothen surface plot. Incase you face any error, just choose only those features from data_frame which are numerical.
'data_frame = data_frame.select_dtypes(include='number')'
from scipy import interpolate
from mpl_toolkits.mplot3d import axes3d, Axes3D
def surface(data_frame, title=None, title_x=0.5, title_y=0.9):
X, Y = np.mgrid[-10:10:complex(0,data_frame.shape[0]),
-10:10:complex(0,data_frame.shape[1])]
Z = data_frame.values
xnew, ynew = np.mgrid[-1:1:80j, -1:1:80j]
tck = interpolate.bisplrep(X, Y, Z, s=0)
znew = interpolate.bisplev(xnew[:,0], ynew[0,:], tck)
fig = go.Figure(data=[go.Surface(z=znew)])
fig.update_layout(template='plotly_dark',
width=800,
height=800,
title = title,
title_x = title_x,
title_y = title_y
)
return fig
I have code that creates a scatterplot matrix and I would like to add a linear regression line to each facet. Code and the current graph are shown below. I currently have a scatterplot for each of the variable combinations for the first five variables in the dataset. I would like to add the regression lines so that when the individual hovers over the line they can also see the correlation.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import plotly.express as px
from sklearn import datasets
from typing import Tuple, List
import plotly.graph_objects as go
from plotly.subplots import make_subplots
def load_data() -> Tuple[np.ndarray, np.ndarray, List[str]]:
"""Load the wine dataset
Returns:
features: the dataset features
target: the labels of the dataset
feature_names: names of each feature
"""
wine = datasets.load_wine()
features = wine['data']
target = wine['target']
feature_names = wine['feature_names']
return features, target, feature_names
features, target, feature_names = load_data()
Data = {
feature_names[0]:features[:,0].tolist(),
feature_names[1]:features[:,1].tolist(),
feature_names[2]:features[:,2].tolist(),
'Target': target.tolist()
}
Data = pd.DataFrame(data = Data)
index_vals = Data['Target'].astype('category').cat.codes
fig = go.Figure(data = go.Splom(dimensions = [
dict(label = feature_names[0],values = Data[feature_names[0]]),
dict(label = feature_names[1],values = Data[feature_names[1]]),
dict(label = feature_names[2],values = Data[feature_names[2]])],
text = Data['Target'],
marker = dict(color = index_vals,showscale = False,size = 8)
))
fig.update_layout(
title='Wine Dataset',
dragmode='select',
width=900,
height=600,
hovermode='closest',
)
fig.show()
With newer versions of plotly, all you need to do is include trendline="ols" in px.scatter. Here's an example that builds on the dataset px.data.tips():
Complete code:
import plotly.express as px
df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip",
trendline = 'ols',
trendline_color_override = 'red',
facet_col="day",
facet_col_wrap = 2)
fig.update_xaxes(matches=None)
fig.show()
I created a plot with Seaborn:
# imports
import random
%matplotlib inline
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
# create some random data
N = 20
rand_matrix = np.asarray([random.randrange(1,11)/10 for _ in range(1, N*N+1) ]).reshape(N,N)
data = np.flip(np.triu(rand_matrix), 1)
df = pd.DataFrame(data, index=pd.date_range(start='2015-01-01', freq='MS',\
periods=N), columns = range(1,N+1))
df[1]=1
# seaborn plot
plt.figure(figsize=(20,20))
sns.heatmap(data = df,
annot = True,
vmin = 0.0,
vmax = 1.0,
cmap = 'PuBuGn')
Here is how I create the Plotly plot:
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=True)
data = [
go.Heatmap(
z=df.values,
x=df.columns.tolist(),
y=df.index.tolist()
)
]
layout = go.Layout(
xaxis = dict(ticks='', nticks=N),
yaxis = dict(ticks='', nticks=N))
fig = go.Figure(data=data, layout=layout)
iplot(fig)
I have following questions:
Seaborn: How do I change the y axis labels to YYYY-MM?
Plotly: How do I get the older data to the top (like with Seaborn)
Plotly: How do I get the data labels displayed in the heatmap (like Seaborn does).
Plotly: I noticed that rendering is much slower than Seaborn. Can it be optimized, if yes how?
2. How do I get the older data to the top?
fig.update_yaxes(autorange="reversed")
3. How do i get the data labels displayed in the heatmap?
ff.create_annotated_heatmap()
4. Can plotly be optimized?
No quick-fixes here.
Plot:
Plotly:
from plotly.offline import iplot
import plotly.graph_objs as go
import plotly.figure_factory as ff
#py.init_notebook_mode(connected=True)
data = [
go.Heatmap(
z=df.values,
x=df.columns.tolist(),
y=df.index.tolist()
)
]
font_colors = ['white', 'black']
fig = ff.create_annotated_heatmap(z=df.values, colorscale='Jet', font_colors=font_colors)
fig.update_layout( yaxis = dict(ticks='', nticks=N))
# Make text size smaller
for i in range(len(fig.layout.annotations)):
fig.layout.annotations[i].font.size = 8
# reverse scales
fig.update_yaxes(autorange="reversed")
fig.show()