Repository: sunpy/sunpy

Issue:
Back (or double?) great circles drawn when used `draw_grid` from any position.
<!-- This comments are hidden when you submit the issue so you do not need to remove them!
Please be sure to check out our contributing guidelines: https://github.com/sunpy/sunpy/blob/master/CONTRIBUTING.rst
Please be sure to check out our code of conduct:
https://github.com/sunpy/sunpy/blob/master/CODE_OF_CONDUCT.rst -->

<!-- Please have a search on our GitHub repository to see if a similar issue has already been posted.
If a similar issue is closed, have a quick look to see if you are satisfied by the resolution.
If not please go ahead and open an issue! -->

### Description
<!-- Provide a general description of the bug. -->
We get the lines behind the sun when using `draw_grid`.


### Expected behavior
<!-- What did you expect to happen. -->
That only the front lines ares shown and the backs are not drawn! (or at least @Cadair said: *weeeird, bug report time*)

### Actual behavior
<!-- What actually happened. -->
<!-- Was the output confusing or poorly described? -->
From SDO:
![Earth_sun](https://user-images.githubusercontent.com/963242/58766702-8e830900-8579-11e9-80c8-dc68f372b289.png)

From other places:
![NoEarth_sun](https://user-images.githubusercontent.com/963242/58766787-b4f57400-857a-11e9-9159-f2fb1882654d.png)


### Steps to Reproduce
<!-- Ideally a code example could be provided so we can run it ourselves. -->
<!-- If you are pasting code, use tripe backticks (```) around your code snippet. -->

1. Get the observer location
```python
sdo_pos = get_horizons_coord('SDO', '2019-03-14 00:10:00')
```

2. Generate a map from such observer
```python
def sun_seen_from(position, name):
    
    # Find out the size of the sun
    solar_r = (constants.radius / position.radius).to(u.arcsec, equivalencies=u.dimensionless_angles())
    th = np.linspace(0 * u.deg, 360 * u.deg)

    # Create a FD map from there
    half_image = 100
    datax, datay = np.mgrid[-half_image:half_image, -half_image:half_image]
    data = 1 - np.sqrt(datax**2 + datay**2)
    coord = SkyCoord(0*u.arcsec, 0*u.arcsec, obstime=position.obstime, observer=position, frame=frames.Helioprojective)
    size = solar_r / half_image / u.pixel
    header = sunpy.map.header_helper.make_fitswcs_header(data, coord,
                                                         reference_pixel=u.Quantity([half_image, half_image]*u.pixel),
                                                         scale=u.Quantity([size, size]),
                                                         instrument='sunlike', detector=f'Sun seen from {name}')

    return sunpy.map.Map(data, header)


sdo_map = sun_seen_from(sdo_pos, name='SDO')
```

3. Plot that map with the `draw_grid`
```python
fig = plt.figure(figsize=(7,8))
ax = fig.add_subplot(1, 1, 1, projection=sdo_test_map)
sdo_test_map.plot(axes=ax)
sdo_test_map.draw_grid(axes=ax)
fig.savefig('Earth_sun.png')
plt.show()
```
4. Repeat for other positions around the heliosphere.

### System Details
<!-- We at least need to know the SunPy version you are using. -->
<!-- We provide a short function in SunPy that will provide some of the below information. -->
<!-- It is sunpy.util.system_info(), this is optional but strongly recommended. -->

  - SunPy Version: v1.0 :tada:
  - Python Version: 3.6.7
  - OS information: Linux using miniconda (conda v.4.5.11)



Discussion:
(I haven't yet tried what's in the original post.)

I haven't been able to reproduce this issue when using a Map object from an actual file (with manually modifying the observer coordinate to be sure).  No back-side grid lines appear.

```python
>>> import astropy.units as u
>>> import sunpy.data.sample
>>> from sunpy.map import Map
>>> m = Map(sunpy.data.sample.EIT_195_IMAGE)
>>> m.meta['hec_z'] *= 1000
>>> m.peek(clip_interval=[5, 99]*u.percent, draw_grid=True)
```
![Figure_1](https://user-images.githubusercontent.com/991759/58777709-9785d180-859d-11e9-8221-673a1aca8cf2.png)
So in collaboration with @astrofrog I think this is something to do with how the coordinates round trip HGS -> pixel -> HGS. WCSAxes uses how that transform behaves (i.e. does input match output) to work out of the lines should be drawn. I have so far got this down to the following behaviour:

A custom map:
```
Point on rear of sun
<SkyCoord (HeliographicStonyhurst: obstime=None): (lon, lat, radius) in (deg, deg, km)
    (-180., 0., 695700.)>
pixel coord
PixelPair(x=<Quantity 27.74920045 pix>, y=<Quantity 104.42559215 pix>)
WCS native coord
<SkyCoord (Helioprojective: obstime=2019-06-03T20:28:40.013, rsun=695700.0 m, observer=<HeliographicStonyhurst Coordinate (obstime=2019-06-03T20:28:40.013): (lon, lat, radius) in (deg, deg, m)
    (-133.44079521, -3.26643583, 2.44214968e+11)>): (Tx, Ty) in arcsec
    (-427.47626507, 23.06636179)>
HGS coord
<SkyCoord (HeliographicStonyhurst: obstime=2019-06-03T20:28:40.013): (lon, lat, radius) in (deg, deg, km)
    (nan, nan, nan)>
```

`AIA_171_IMAGE` map:
```
Point on rear of sun
<SkyCoord (HeliographicStonyhurst: obstime=None): (lon, lat, radius) in (deg, deg, km)
    (-180., 0., 695700.)>
pixel coord
PixelPair(x=<Quantity 510.13144745 pix>, y=<Quantity 511.24706341 pix>)
WCS native coord
<SkyCoord (Helioprojective: obstime=2011-06-07T06:33:02.770, rsun=696000000.0 m, observer=<HeliographicStonyhurst Coordinate (obstime=2011-06-07T06:33:02.770): (lon, lat, radius) in (deg, deg, m)
    (359.99593689, 0.04787238, 1.51846026e+11)>): (Tx, Ty) in arcsec
    (-0.06671055, 0.78599687)>
HGS coord
<SkyCoord (HeliographicStonyhurst: obstime=2011-06-07T06:33:02.770): (lon, lat, radius) in (deg, deg, km)
    (-0.00808742, 0.09528755, 695999.99999955)>
```

I don't understand why the custom map returns NaNs for the last HPC -> HGS transform. *Investigations continue*.
The culprit is `rsun=695700.0 m`

Resolving patch:
diff --git a/sunpy/map/header_helper.py b/sunpy/map/header_helper.py
--- a/sunpy/map/header_helper.py
+++ b/sunpy/map/header_helper.py
@@ -49,8 +49,10 @@ def make_fitswcs_header(data, coordinate, reference_pixel: u.pix = None,
         Coordinate object to get meta information for map header.
     reference_pixel :`~astropy.units.Quantity` of size 2, optional
         Reference pixel along each axis. These are expected to be Cartestian ordered, i.e
-        the first index is the x axis, second index is the y axis.
-        Defaults to the center of data array, ``(data.shape[1] + 1)/2., (data.shape[0] + 1)/2.)``.
+        the first index is the x axis, second index is the y axis. Defaults to
+        the center of data array, ``(data.shape[1] - 1)/2., (data.shape[0] - 1)/2.)``,
+        this argument is zero indexed (Python convention) not 1 indexed (FITS
+        convention).
     scale : `~astropy.units.Quantity` of size 2, optional
         Pixel scaling along x and y axis (i.e. the spatial scale of the pixels (dx, dy)). These are
         expected to be Cartestian ordered, i.e [dx, dy].
@@ -124,8 +126,8 @@ def make_fitswcs_header(data, coordinate, reference_pixel: u.pix = None,
     meta_wcs['crval1'], meta_wcs['crval2'] = (coordinate.spherical.lat.to_value(meta_wcs['cunit1']),
                                               coordinate.spherical.lon.to_value(meta_wcs['cunit2']))
 
-    meta_wcs['crpix1'], meta_wcs['crpix2'] = (reference_pixel[0].to_value(u.pixel),
-                                              reference_pixel[1].to_value(u.pixel))
+    meta_wcs['crpix1'], meta_wcs['crpix2'] = (reference_pixel[0].to_value(u.pixel) + 1,
+                                              reference_pixel[1].to_value(u.pixel) + 1)
 
     meta_wcs['cdelt1'], meta_wcs['cdelt2'] = (scale[0].to_value(meta_wcs['cunit1']/u.pixel),
                                               scale[1].to_value(meta_wcs['cunit2']/u.pixel))
@@ -204,7 +206,7 @@ def _get_observer_meta(coordinate):
     coord_meta['hgln_obs'] = coordinate.observer.lon.to_value(u.deg)
     coord_meta['hglt_obs'] = coordinate.observer.lat.to_value(u.deg)
     coord_meta['dsun_obs'] = coordinate.observer.radius.to_value(u.m)
-    coord_meta['rsun_ref'] = coordinate.rsun.to_value()
+    coord_meta['rsun_ref'] = coordinate.rsun.to_value(u.m)
     coord_meta['rsun_obs'] = np.arctan(coordinate.rsun / coordinate.observer.radius).to_value(u.arcsec)
 
     return coord_meta


Test patch:
diff --git a/sunpy/map/tests/test_header_helper.py b/sunpy/map/tests/test_header_helper.py
--- a/sunpy/map/tests/test_header_helper.py
+++ b/sunpy/map/tests/test_header_helper.py
@@ -87,7 +87,7 @@ def test_make_fits_header(map_data, hpc_test_header, hgc_test_header,
     # Check that correct information is in header MetaDict including observer for HPC
     header = sunpy.map.make_fitswcs_header(map_data, hpc_test_header)
     assert header['crval1'] == 0
-    assert header['crpix1'] == 5.5
+    assert header['crpix1'] == 6.5
     assert header['ctype1'] == 'HPLN-TAN'
     assert header['dsun_obs'] == hpc_test_header.frame.observer.radius.to_value(u.m)
     assert isinstance(WCS(header), WCS)
diff --git a/sunpy/net/tests/test_fido.py b/sunpy/net/tests/test_fido.py
--- a/sunpy/net/tests/test_fido.py
+++ b/sunpy/net/tests/test_fido.py
@@ -137,6 +137,8 @@ def test_unified_response():
 
 
 def test_no_time_error():
+    # TODO: work out why this is failing sometimes.
+    from sunpy.net import attrs as a
     query = (a.Instrument('EVE'), a.Level(0))
     with pytest.raises(ValueError) as excinfo:
         Fido.search(*query)