Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different projections for different subplots? #211

Closed
miniufo opened this issue Jul 31, 2020 · 4 comments
Closed

Different projections for different subplots? #211

miniufo opened this issue Jul 31, 2020 · 4 comments

Comments

@miniufo
Copy link

miniufo commented Jul 31, 2020

I would like two subplots. The left subplot is plotted with a kwarg proj='robin' while the right one does not need proj. This is sometimes common when the right plot is an (zonal) average of the left one. See the example below:
image

If I use the following code:

fig, ax = pplt.subplots(ncols=2, nrows=1, proj='robin')

Two panels will both use proj='robin'. So is it possible to have some of the subplots use proj and keep the rest use the default (non-projection) plot?

@mickaellalande
Copy link
Contributor

Hi @miniufo, it looks actually possible. I don't know if it is well-formatted for these kinds of plots with projections, but so far here are two examples that I succeded to make (one with and without panels):

import proplot as plot
import xarray as xr
da = xr.tutorial.open_dataset('air_temperature').air.mean('time') - 273.15
  1. Without panels (see here for other examples: https://proplot.readthedocs.io/en/latest/projections.html)
fig, axs = plot.subplots(nrows=1, ncols=2, proj=('cyl', None), wratios=(5, 1), axwidth=4)

# First axis
ax = axs[0]
m = ax.contourf(da, cmap='CoolWarm', symmetric=True)
ax.colorbar(m, label='Air Temperature [°C]', loc='b')

ax.format(
   title='Title 1', coast=True, labels=True, borders=True, lonlines=20, latlines=10,
   latlim=(da.lat.min().values, da.lat.max().values), lonlim=(da.lon.min().values, da.lon.max().values)
)

# Second axis
ax = axs[1]
ax.plot(da.mean('lon'), da.lat)
ax.format(title='Title 2', xlabel='°C', ylabel='latitude', ytickloc='right', yticklabelloc='right')

# Format all axs
axs.format(abc=True)
fig.save('panel_1.jpg', dpi=300)

panel_1

  1. With panels (https://proplot.readthedocs.io/en/latest/insets_panels.html#Panel-axes)
fig, axs = plot.subplots(nrows=1, ncols=1, proj='cyl', includepanels=True, axwidth=4)

# Plot
ax = axs[0]
ax.contourf(da, cmap='CoolWarm', symmetric=True, colorbar='b', colorbar_kw={'label': 'Air Temperature [°C]'} )

ax.format(
    title='Title 1', coast=True, labels=True, borders=True, lonlines=20, latlines=10,
    latlim=(da.lat.min().values, da.lat.max().values), lonlim=(da.lon.min().values, da.lon.max().values)  
)

# Panel
pax = ax.panel('r', width=0.8)
pax.plot(da.mean('lon'), da.lat)
pax.format(ylabel='latitude', title='Title 2')

# Format all axs
axs.format(abc=True)
fig.save('panel_2.jpg', dpi=300)

panel_2

Some small problems that I see:

  • the latitudes are actually not exactly at the same level, maybe due to the projection or padding in the panels (I don't know if it is easy to fix this)?
  • the xlabel is not taken into account for the panels
  • the option abc=True is not applied for the panel (I don't know if it is suitable or not), I guess you can add it manually with a left-title ltitle in the format

I guess @lukelbd that develop this package could answer better than me on these small issues.


Proplot version: 0.6.4
Matplotlib version: 3.2.0

@miniufo
Copy link
Author

miniufo commented Aug 1, 2020

Hi @mickaellalande that is awesome!

I've tried proj=('cyl', ''), but didn't notice it should be proj=('cyl', None). Thanks very much for your examples. I would like to follow the first one. Also want to know whether the first problem could be fixed:

the latitudes are actually not exactly at the same level, maybe due to the projection or padding in the panels (I don't know if it is easy to fix this)?

@zmoon
Copy link
Contributor

zmoon commented Aug 1, 2020

Also want to know whether the first problem could be fixed:

the latitudes are actually not exactly at the same level, maybe due to the projection or padding in the panels (I don't know if it is easy to fix this)?

I think it is just because the y ax is not "tight". If you add ax.autoscale(enable=True, axis="y", tight=True) to the # Second axis block, they line up much better.

panel_1

Maybe there is a way to have ProPlot do that, though?

@lukelbd
Copy link
Collaborator

lukelbd commented Jun 29, 2021

Hi @zmoon and @mickaellalande, the misalignment of panels A and B is related to #79, #178, #199.

Basically "axis sharing" is not possible between "geographic" plots like in your example, because "axis sharing" doesn't make sense for a lot of non-rectangular projections, and projections often have longitude/latitude labels on the top/right of subplots (proplot currently doesn't support sharing of labels on the top/right). In the future I plan to support axis sharing for simple rectangular projections like Mercator and Plate Carrée (as in your example).

For now this issue duplicates those others, so I'll close it. As a workaround, set the latitude limits manually:

import proplot as plot
fig, axs = plot.subplots(ncols=2, proj=('cyl', None))  # or ('cyl', 'cartesian')
axs[0].format(latlim=(15, 75))
axs[1].format(ylim=(15, 75))

Also "panels" are excluded from the a-b-c labelling system -- that's intended behavior.

@lukelbd lukelbd closed this as completed Jun 29, 2021
@lukelbd lukelbd changed the title some of the subplots need map projection Different projections for different subplots? Jun 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants