Plotly Express: Order of elements in plot (python) - plotly-python

When using Plotly Express, the easiest way to add multiple traces seems to be the "Add Trace Convenience Methods", such as fig.add_scatter. My problems is that when using this method, it seems to me like there is no way to to force this added trace to the top of the drawing.
The following example code produces a graph where the red "trace 1" markers are hidden behind the blue markers created using Plotly Express. How could one go about putting this layer on top of the draw order? I have tried messing around with the stackgroup parameter, but this had no effect.
import numpy as np
import plotly.express as px
fig = px.scatter(x=np.random.rand(20000), y=np.random.rand(20000))
fig.add_scatter(x=np.random.rand(5), y=np.random.rand(5),
mode='markers', marker=dict(size=40))
fig.show()

Not in Plotly Express, because that doesn't support multiple axes, but:
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(
go.Scatter(x=np.random.rand(20000), y=np.random.rand(20000)),
secondary_y=False
)
fig.add_trace(
go.Scatter(x=np.random.rand(5), y=np.random.rand(5),
mode='markers', marker=dict(size=40)),
secondary_y=True
)
fig.show()
You might then need to align both axes as explained here.

Related

Is there a function in plotly that is equivalent to plt.axes('scaled') in matplotlib for the aspect ratio of a graph?

I want to plot some coordinates using Plotly express because it allows me a more interactive approach, but I can not find the way to control the scale in the axis in the way I can manage with matplotlib.pyplot in one single line
plt.axis("scaled")
Could you please share some suggestions? Thanks.
Here is the code using Plotly express:
fig = px.scatter(coordinates_utm, x='EASTING', y='NORTHING', title=name,
hover_name=coordinates_utm.index,
hover_data={'NORTHING':':.6f','EASTING': ':.6f'})
fig.add_trace(px.scatter(coordinates_utm_lineal, x='x', y='ylineal',color_discrete_sequence=['red']).data[0])
Here is the code using plt:
fig.show()
plt.figure()
plt.scatter(coordinates_utm_lineal.x,coordinates_utm_lineal.ylineal,s=2)
plt.scatter(coordinates_utm.EASTING,coordinates_utm.NORTHING, s=2)
plt.axis("scaled")
plt.show()
This is my current output
Sadly, you didn't provide a fully reproducible example, so I'm going to create my own.
Also, I'm not really familiar with plt.axis("scaled"), as I usually use plt.axis("equal"). Reading the documentation associated to plt.axis, they appear to be somewhat similar. See if the following answer can satisfy your needs.
import plotly.express as px
import numpy as np
t = np.linspace(0, 2*np.pi)
x = np.cos(t)
y = np.sin(t)
fig = px.scatter(x=x, y=y)
fig.layout.yaxis.scaleanchor="x"
fig.show()

How to show legend in missingno matrix?

So far, I have managed to spawn a legend box and have managed to put it outside the chart. But it is showing the same colours for both the labels (white and white) whereas I would prefer it to show white and gray.
import missingno as msno
msno.matrix(X_train, figsize=(15,10), sparkline=False, p=0);
plt.legend(['missing','not missing'],loc='center left', bbox_to_anchor=(1, 0.5))
You'll have to craft the legend by hand. matplotlib has a legend guide showing how you can do this. The section describing "proxy artists" in particular is relevant to your use case. I haven't tested it, but the following should work:
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import missingno as msno
msno.matrix(...your data...)
gray_patch = mpatches.Patch(color='gray', label='Data present')
white_patch = mpatches.Patch(color='white', label='Data absent ')
plt.legend(handles=[gray_patch, white_patch])
plt.show()

Matplotlib graph does not show in Python Interactive Window

The following is my code, but I can't get the plot to show on my Visual Studio Code even though I am running this on the Python Interactive Window, which should usually show a graph plot after running. The tables are showing just fine. I also do not get a default graph which pops up like it normally should. What am I doing wrong?
import yfinance as yf
import pandas as pd
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import talib
df = pd.read_csv('filename.csv')
df = df.sort_index()
macd, macdsignal, macdhist = talib.MACD(df['Close'], fastperiod=12, slowperiod=26, signalperiod=9)
macd = macd.to_list()
macdsignal = macdsignal.to_list()
macdhist = macdhist.to_list()
df['macd'], df['macdsignal'], df['macdhist'] = macd,macdsignal,macdhist
ax = plt.gca()
print(df.columns)
df.plot(kind='line',x='Date',y='macd', color='blue',ax=ax)
df.plot(kind='line',x='Date',y='macdsignal', color='red', ax=ax)
plt.show()
The csv file has data that looks like this
The issue was with matplotlib.use('agg'), which does not support the show() function. This prevented the graph from being displayed on Visual Studio's Interactive Window. The matplotlib.use('agg') method can, however, be used for saving your graph in a .png format.
According to Matplotlib.org, agg is "the canonical renderer for user interfaces, which uses the Anti-Grain Geometry C++ library to make a raster (pixel) image of the figure". More information can be found at this link here

How to add a point-feature shapefile to map using cartopy

I have two shapefiles. One is a point feature shapefile, named "point.shp", the other is a polygon shapefile named "polygon.shp". Both I want to add to a map using cartopy.
I managed to add the "polygon.shp", but failed with the "point.shp".
Here's my code:
import matplotlib.pyplot as plt
from cartopy import crs
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
ax = plt.axes(projection=crs.PlateCarree())
# add the polygon file, worked
ax.add_geometries(Reader("polygon.shp").geometries(), crs.PlateCarree(), facecolor='w')
# or(also worked):
ax.add_feature(ShapelyFeature(Reader("polygon.shp").geometries(), crs.PlateCarree(), facecolor='r'))
# but these two ways both failed with the "point.shp"
ax.add_geometries(Reader("point.shp").geometries(), crs.PlateCarree())
# or, this doesn't work neither:
ax.add_feature(ShapelyFeature(Reader("polygon.shp").geometries(), crs.PlateCarree(), facecolor='r'))
Does any one know how to do this, or why, without retrieving all the points' x, y coords and then plotting them?
And with coordinates(x, y values), ax.plot() works, but ax.scatter() fails, why?
Thanks
add_geometries currently turns a geometry into a polygon and then colours it appropriately, which of course means that when you pass points the add_geometries, the polygons are not visible. Potentially cartopy could do a better job of this in the future, but in the meantime, it sounds like you just want to use something like scatter to visualize your data.
You can achieve this by getting the x and y coordinate values out of the geometry and passing these straight on to scatter with the appropriate transform:
import cartopy.crs as ccrs
import cartopy.io
import matplotlib.pyplot as plt
fname = cartopy.io.shapereader.natural_earth(resolution='10m',
category='cultural',
name='populated_places_simple')
plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.Robinson())
ax.set_title('Populated places of the world.')
ax.coastlines()
points = list(cartopy.io.shapereader.Reader(fname).geometries())
ax.scatter([point.x for point in points],
[point.y for point in points],
transform=ccrs.Geodetic())
plt.show()
HTH

Annotating a box outside the box, matplotlib

I want the text to appear beside the box instead of inside it:
Here is what I did:
import matplotlib as mpl
import matplotlib.pyplot as plt
from custombox import MyStyle
fig = plt.figure(figsize=(10,10))
legend_ax = plt.subplot(111)
legend_ax.annotate("Text",xy=(0.5,0.5),xycoords='data',xytext=(0.5, 0.5),textcoords= ('data'),ha="center",rotation = 180,bbox=dict(boxstyle="angled, pad=0.5", fc='white', lw=4, ec='Black'))
legend_ax.text(0.6,0.5,"Text", ha="center",size=15)
Here is what it gives me:
Note: custombox is similar to the file that is written in this link:
http://matplotlib.org/1.3.1/users/annotations_guide.html
My ultimate aim is to make it look legend like where the symbol (angled box) appears beside the text that represents it.
EDIT 1: As suggested by Ajean I have annotated text separately but I can't turn of the text within the arrow
One way to do it would be to separate the text and the bbox (which you can reproduce using an arrow). The following gives me something close to what you want, I think.
import matplotlib.pyplot as plt
from matplotlib import patches
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111)
ax.annotate("Text", (0.4,0.5))
bb = patches.FancyArrow(0.5,0.5,0.1,0.0,length_includes_head=True, width=0.05,
head_length=0.03, head_width=0.05, fc='white', ec='black',
lw=4)
ax.add_artist(bb)
plt.show()
You can futz with the exact placement as needed. I'm not an expert on all the kwargs, so this may not be the best solution, but it will work.